问题 更新到.net 4.0后的wcf回调异常


我有一个使用DualHttpBindings回调的wcf服务。该服务在找到它们时将客户端(用于长时间运行的搜索)的搜索结果数据推回。

这在.Net 3.5中运行良好。自从我更新到.Net 4.0以来,它实际上杀死了IIS工作进程的System.Runtime.FatalException。我不知道如何开始解决这个问题。任何建议赞赏。

结果事件日志中的信息粘贴在下面:


发生了未处理的异常   这个过程终止了。

应用ID:/ LM / W3SVC / 2 / ROOT / CP

进程ID:5284

>例外:   System.Runtime.FatalException

>消息:未设置对象引用   一个对象的实例。

堆栈跟踪: 在   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&   rpc)at   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&   rpc)at   System.ServiceModel.Dispatcher.MessageRpc.Process(布尔   isOperationContextSet)at   System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(的RequestContext   request,Boolean cleanThread,   的OperationContext   currentOperationContext)at   System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(的RequestContext   请求,OperationContext   currentOperationContext)at   System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult的   结果)在   System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult的   结果)在   System.Runtime.AsyncResult.Complete(布尔   完成同步)   System.Runtime.InputQueue1.AsyncQueueReader.Set(Item item) at System.Runtime.InputQueue1.Dispatch()   在   System.ServiceModel.Channels.ReliableDuplexSessionChannel.ProcessDuplexMessage(WsrmMessageInfo   信息)   System.ServiceModel.Channels.ReliableDuplexSessionChannel.HandleReceiveComplete(IAsyncResult的   结果)在   System.ServiceModel.Channels.ReliableDuplexSessionChannel.OnReceiveCompletedStatic(IAsyncResult的   结果)在   System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult的   结果)在   System.Runtime.AsyncResult.Complete(布尔   完成同步)   System.ServiceModel.Channels.ReliableChannelBinder1.InputAsyncResult1.OnInputComplete(IAsyncResult的   结果)在   System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult的   结果)在   System.Runtime.AsyncResult.Complete(布尔   完成同步)   System.Runtime.InputQueue1.AsyncQueueReader.Set(Item item) at System.Runtime.InputQueue1.Dispatch()   在   System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32的   errorCode,UInt32 numBytes,   NativeOverlapped * nativeOverlapped)
  在   System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32的   错误,UInt32 bytesRead,   NativeOverlapped * nativeOverlapped)
  在   System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32的   errorCode,UInt32 numBytes,   NativeOverlapped * pOVERLAP)

> InnerException: > System.NullReferenceException

信息:对象引用未设置为   一个对象的实例。

堆栈跟踪: 在   System.Web.HttpApplication.ThreadContext.Enter(布尔   setImpersonationContext)at   System.Web.HttpApplication.OnThreadEnterPrivate(布尔   setImpersonationContext)at   System.Web.AspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback   回调,对象状态)at   System.Web.AspNetSynchronizationContext.CallCallback(SendOrPostCallback   回调,对象状态)at    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&   RPC)


7240
2018-06-02 16:39


起源



答案:


好的 - 我找到了答案。非常奇怪,但只是将以下属性放在WCF回调包装类上:

[CallbackBehavior(UseSynchronizationContext=false)]

感谢Cauldwell.net的回答: http://www.cauldwell.net/patrick/blog/CategoryView,category,CodeGen.aspx

来自cauldwell.net:

事实证明,问题就在于此   ASP.NET使用(默认情况下)一点点   事情叫做   的SynchronizationContext。就像我一样   可以告诉我(我还没有研究过这个   彻底,说实话)其中一个   工作,以确保任何   回调在UI线程上运行,   从而避免了打电话的需要   Control.Invoke就像你一样   的WinForms。在我的情况下,额外的   锁给了适合的东西,它   我试图清理东西   不再有的线程,   因此为NullReferenceException。


15
2018-06-02 20:38



+1票。谢谢詹姆斯,你节省我的时间:) - Afshin Mehrabani
这就是诀窍!虽然我的方案与文章有点不同,因为在调用回调方法之前抛出了异常。 - Jan


答案:


好的 - 我找到了答案。非常奇怪,但只是将以下属性放在WCF回调包装类上:

[CallbackBehavior(UseSynchronizationContext=false)]

感谢Cauldwell.net的回答: http://www.cauldwell.net/patrick/blog/CategoryView,category,CodeGen.aspx

来自cauldwell.net:

事实证明,问题就在于此   ASP.NET使用(默认情况下)一点点   事情叫做   的SynchronizationContext。就像我一样   可以告诉我(我还没有研究过这个   彻底,说实话)其中一个   工作,以确保任何   回调在UI线程上运行,   从而避免了打电话的需要   Control.Invoke就像你一样   的WinForms。在我的情况下,额外的   锁给了适合的东西,它   我试图清理东西   不再有的线程,   因此为NullReferenceException。


15
2018-06-02 20:38



+1票。谢谢詹姆斯,你节省我的时间:) - Afshin Mehrabani
这就是诀窍!虽然我的方案与文章有点不同,因为在调用回调方法之前抛出了异常。 - Jan