我在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; }
}
}