异步WCF方法等待后,WebOperationContext为null

时间:2012-11-08 13:44:16

标签: c# wcf async-await

在以下示例中,该方法作为WCF服务操作公开,并且该服务在IIS中承载。 在进入函数时,WebOperationContext.Current按预期设置。然而,在await完成等待之后,WebOperationContext.Current被设置为null。

        public async Task TestAsync()
    {
        //WebOperationContext.Current is set

        Task t = new Task(()=>Thread.Sleep(10000));

        t.Start();

        await t;

        //WebOperationContext.Current is null
    }

这似乎是一个缺点,所以我想知道是否有人知道这一点以及是否有任何好的方法。我意识到我可以在局部变量中缓存对conext的引用,但这看起来不太好。

更新

一种有效的方法是

            public async Task TestAsync()
    {
        WebOperationContext ctx = WebOperationContext.Current;

        Task t = new Task(()=>Thread.Sleep(10000));

        t.Start();

        await t;

        //ctx is set        
    }

而且,正如其他人所暗示的,我可以做到这一点

        public async Task TestAsync()
    {
        CallContext.LogicalSetData("WebOperationContext.Current", WebOperationContext.Current);

        Task t = new Task(()=>Thread.Sleep(10000));

        t.Start();

        await t;

        WebOperationContext ctx = (WebOperationContext)CallContext.LogicalGetData("WebOperationContext.Current");
    }

每个产品的性能和线程安全性会产生什么影响?

1 个答案:

答案 0 :(得分:5)

我听说WCF团队正在考虑OperationContext.Current的解决方案,我希望他们也能解决WebOperationContext.Current问题。请参阅this SO post(请注意,Jon Cole是MS WCF团队的成员。)

与此同时,您可以捕获变量中的值(提高可测试性,这是我推荐的),将其添加到LogicalCallContext,或者安装自己的SynchronizationContext(这会很棘手)因为你是在IIS中托管的,它使用自己的SynchronizationContext)。