You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置IClientMessageInspector后,WCF服务async/await调用丢失HttpContext问题咨询

问题:未使用ConfigureAwait(false)的async/await场景下,带IClientMessageInspector的WCF服务上下文同步问题

我们的项目基于.NET Framework 4.5+,用WcfUtils生成了包含异步方法的WCF代理类。在web.config的system.serviceModel节点中配置了自定义的BehaviourExtensionElement,用来注册一个实现IClientMessageInspector的自定义检查器。这个检查器的AfterReceiveReply方法需要访问HttpContext.Current.Items[stringKey]。

现在遇到的问题是:尽管整个执行路径都没用到ConfigureAwait(false),但在AfterReceiveReply方法里HttpContext.Current始终为null。日志显示,调用base.Channel.MyMethod异步方法的前后都存在上下文(因为WcfUtil生成的代理不使用await,只返回Task)。搜了大量资料,没找到关于MessageInspector存在时异步延续上下文的具体说明,搞不懂为什么它的同步机制和主调用不一样。


编辑1:添加中间检查器验证

我创建了一个虚拟的MessageInspector,发现所有await调用进入检查器时都没有上下文:当前认证用户变成了应用池用户,HttpContext.Current为null,执行堆栈如下:

à MyNamespace.InTheMiddleMessageInspector.AfterReceiveReply(Message& reply, Object correlationState) dans D:\Builds\sfpauw14759_1\_work\379\s\Client\AccueilClient\SX00.SXCLT00A.AccueilClient\InTheMiddleMessageInspector.cs:ligne 76
à System.ServiceModel.Dispatcher.ImmutableClientRuntime.AfterReceiveReply(ProxyRpc& rpc)
à System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
à System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
à System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass7_0`1.<CreateGenericTask>b__0(IAsyncResult asyncResult)
à System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
à System.Threading.Tasks.TaskFactory`1.<>c__DisplayClass44_0`3.<FromAsyncImpl>b__0(IAsyncResult iar)
à System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
à System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishSend(IAsyncResult result, Boolean completedSynchronously)
à System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.SendCallback(IAsyncResult result)
à System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
à System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
à System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(IAsyncResult result)
à System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
à System.Net.LazyAsyncResult.Complete(IntPtr userToken)
à System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
à System.Net.ContextAwareResult.Complete(IntPtr userToken)
à System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
à System.Net.HttpWebRequest.ProcessResponse()
à System.Net.HttpWebRequest.SetResponse(CoreResponseData coreResponseData)
à System.Net.ConnectionReturnResult.SetResponses(ConnectionReturnResult returnResult)
à System.Net.Connection.ReadComplete(Int32 bytesRead, WebExceptionStatus errorStatus)
à System.Net.LazyAsyncResult.Complete(IntPtr userToken)
à System.Net.ContextAwareResult.Complete(IntPtr userToken)
à System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
à System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
à System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

编辑2:离开MessageInspector后上下文恢复正常

返回到主代码分支时,上下文恢复正常,此时执行堆栈如下:

à MyNamespace.MyClass.<MyMethodAsync>d__5`2.MoveNext()
à System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
à System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
à System.Web.Util.SynchronizationHelper.SafeWrapCallback(Action action)
à System.Threading.Tasks.Task.Execute()
à System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
à System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
à System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
à System.Threading.ThreadPoolWorkQueue.Dispatch()

看起来问题出在ASP.NET调用MessageInspector的方式上。


内容的提问来源于stack exchange,提问作者bkqc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 00:04:53