C# 异步WCF方法WebOperationContext在等待后为null
在下面的示例中,该方法作为WCF服务操作公开,该服务托管在IIS中。 在进入函数时,WebOperationContext.Current按预期设置。但是,在等待完成后,WebOperationContext.Current被设置为nullC# 异步WCF方法WebOperationContext在等待后为null,c#,wcf,async-await,C#,Wcf,Async Await,在下面的示例中,该方法作为WCF服务操作公开,该服务托管在IIS中。 在进入函数时,WebOperationContext.Current按预期设置。但是,在等待完成后,WebOperationContext.Current被设置为null public async Task TestAsync() { //WebOperationContext.Current is set Task t = new Task(()=>Thread
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");
}
在性能和线程安全方面,每种方法都会有什么影响?我听说WCF团队正在考虑
OperationContext.Current
的解决方案,我希望他们也会解决WebOperationContext.Current
。请参阅(注意乔恩·科尔是微软WCF团队的成员)
同时,您可以捕获变量中的值(这提高了可测试性,这是我的建议),将其添加到
LogicalCallContext
,或者安装您自己的SynchronizationContext
(这会很棘手,因为您托管在IIS中,它使用自己的SynchronizationContext
),但我没有意识到JC也在团队中,因此我想我会再问一次。它似乎是一个很好的修复候选,尽管我不确定会涉及到什么诡计,因为wait意味着下面的代码块将在不同的线程上执行Wait
将在“上下文”上捕获并恢复,但这通常是由主机而不是WCF确定的同步上下文(并且没有“挂钩”)用于插入您自己的数据与上下文一起流动,而不是LogicalCallContext
,如果WCF团队一直使用它,这将对性能产生相当大的影响,并且可能会通过远程调用和其他应用程序域流动)。所以我不知道他们将如何解决这个问题我很想听听您认为捕获变量值的最佳方法是什么,仅仅存储一个本地引用并使用它是否安全,或者我应该做更多吗?使用本地(或实例)变量是安全的;我希望这比LogicalCallContext
更快。但是我会考虑一个重构,它将从<代码> TEST SASYNC 完全IOC中删除代码> WebOperationContext <代码>,可能使用DI。这样,您的TestAsync
就很容易进行测试。