我在IIS中托管我的.NET 4.5 WCF服务。 有一段名为“BusinessContext”(BC)的信息存储在OperationContext.Current实例中,因此任何下游逻辑都可以访问它。从IIS中托管的WCF使用AspNetSynchronizationContext
一切正常,直到我引入异步/等待,我碰到了this issue。 @ stephen-cleary提到ASP.NET使用异步友好的AspNetSynchronizationContext来保持跨线程的HttpContext.Current。由于我在IIS中托管,我想我应该能够利用WCF中的AspNetSyncCtx,并使用HttpContext.Current而不是OperationContext来存储BC。
我从零开始创建了一个WCF服务,它在Web.config中默认设置了targetFramework = 4.5,aspnet:UseTaskFriendlySynchronizationContext = true和aspNetCompatibilityEnabled = true。我还添加了AspNetCompatibilityRequirements =我的服务必需的。
在运行时我看到HttpContext.Current存在,但SynchronizationContext.Current为null。在等待HttpContext变为null之后,这是因为没有SyncCtx而预期的。当需要aspcompatibility时,不应该将它设置为AspNetSyncCtx吗? AspNetSyncCtx如何在ASP.NET中设置?
- 可能的解决方案。
正在关注@ Stephen-cleary的here我继续并定义了一个自定义的SynchronizationContext来保留跨线程的OperationContext。
我想听听社区对此实施的意见。谢谢。
public class OperationContextSynchronizationContext : SynchronizationContext
{
public override void Post(SendOrPostCallback d, object state)
{
OperationContext opCtx = OperationContext.Current;
InternalState internalState = new InternalState()
{
OpCtx = opCtx,
Callback = d,
State = state,
SyncCtx = this
};
ThreadPool.QueueUserWorkItem(new WaitCallback(InternalInvoker), internalState);
}
private void InternalInvoker(object internalState)
{
InternalState internalSt = internalState as InternalState;
SynchronizationContext.SetSynchronizationContext(internalSt.SyncCtx);
using (new OperationContextScope(internalSt.OpCtx))
{
internalSt.Callback.Invoke(internalSt.State);
}
}
private class InternalState
{
public SynchronizationContext SyncCtx { get; set; }
public OperationContext OpCtx { get; set; }
public SendOrPostCallback Callback { get; set; }
public object State { get; set; }
}
}