Dot-Net
在 WCF 服務中使用 async/await 時,OperationContext.Current 在第一次等待後為空
我在 .NET 4.5 中使用 async/await 模式在 WCF 中實現一些服務方法。範例服務:
合同:
[ServiceContract(Namespace = "http://async.test/")] public interface IAsyncTest { Task DoSomethingAsync(); }執行:
MyAsyncService : IAsyncTest { public async Task DoSomethingAsync() { var context = OperationContext.Current; // context is present await Task.Delay(10); context = OperationContext.Current; // context is null } }我遇到的問題是第一次
awaitOperationContext.Current返回後null我無法訪問OperationContext.Current.IncomingMessageHeaders.在這個簡單的範例中,這不是問題,因為我可以在
await. 但在現實世界OperationContext.Current中,是從呼叫堆棧的深處訪問的,我真的不想為了進一步傳遞上下文而更改大量程式碼。有沒有辦法在
await不手動將其向下傳遞的情況下獲取操作上下文?
我認為您最好的選擇是實際擷取它並手動傳遞它。您可能會發現這提高了程式碼的可測試性。
也就是說,還有其他幾個選擇:
- 將其添加到
LogicalCallContext.- 安裝你自己的
SynchronizationContext,它會OperationContext.Current在它執行時設置Post;這就是 ASP.NET 保留其HttpContext.Current.- 安裝你自己的
TaskScheduler哪套OperationContext.Current。您可能還想在 Microsoft Connect 上提出此問題。
不幸的是,這不起作用,我們將在未來的版本中看到修復。
同時,有一種方法可以將上下文重新應用到目前執行緒,這樣您就不必傳遞對象:
public async Task<double> Add(double n1, double n2) { OperationContext ctx = OperationContext.Current; await Task.Delay(100); using (new OperationContextScope(ctx)) { DoSomethingElse(); } return n1 + n2; }在上面的範例中,**DoSomethingElse()**方法將按預期訪問 OperationContext.Current。