【问题标题】:async WCF method WebOperationContext is null after await等待后异步 WCF 方法 WebOperationContext 为空
【发布时间】:2012-11-08 13:44:15
【问题描述】:

在以下示例中,该方法公开为 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");
    }

在性能和线程安全方面会产生什么影响?

【问题讨论】:

    标签: c# wcf async-await


    【解决方案1】:

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

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

    【讨论】:

    • 我看过那个帖子,但没有意识到 JC 在团队中,因此我想我会再问一次。这似乎是一个很好的修复候选者,虽然我不确定会涉及什么技巧,因为 await 意味着以下代码块将在不同的线程上执行。
    • 之所以复杂,是因为 WCF 与主机无关。 await 将捕获并在“上下文”上恢复,但这通常是 SynchronizationContext,由主机而不是 WCF 确定(并且没有用于插入您自己的数据以随上下文流动的“钩子”,除了LogicalCallContext,如果 WCF 团队一直使用它,这将对性能产生相当大的影响,并且还可能通过远程调用流入其他应用程序域)。所以我不知道他们会如何解决这个问题。 ;)
    • 我很想听听您认为在变量中捕获值的最佳方法是什么,仅存储本地引用并使用它是否安全,还是我应该做更多?
    • 使用本地(或实例)变量是安全的;我希望这比LogicalCallContext 更快。但我会考虑进行重构,从TestAsync 中完全删除WebOperationContext - IoC,可能使用DI。这样你的TestAsync 就很容易测试了。
    猜你喜欢
    • 1970-01-01
    • 2012-02-06
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多