Исключение обратного вызова wcf после обновления до .net 4.0
У меня есть служба wcf, которая использует обратные вызовы с помощью DualHttpBindings. Служба отталкивает возвращаемые данные результатов поиска клиенту (для продолжительного поиска) по мере их нахождения.
Это отлично работало в .Net 3.5. Поскольку я обновлялся до .Net 4.0, он запускает System.Runtime.FatalException, который фактически убивает рабочий процесс IIS. Я понятия не имею, как начать исправление. Любые рекомендации оценены.
Информация из результирующих журналов событий вставляется ниже:
Произошло необработанное исключение и процесс был прерван.
Идентификатор приложения:/LM/W3SVC/2/ROOT/CP
Идентификатор процесса: 5284
Исключение: System.Runtime.FatalException
Сообщение: ссылка на объект не установлена экземпляр объекта.
StackTrace: при System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4 (MessageRpc & rpc) при System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31 (MessageRpc & rpc) при System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) при System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext) в System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext запрос, OperationContext currentOperationContext) в System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult результат) в System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult результат) в System.Runtime.AsyncResult.Complete(Boolean завершено синхронно) при System.Runtime.InputQueue 1.AsyncQueueReader.Set(Item
item) at
System.Runtime.InputQueue
1.Dispatch() в System.ServiceModel.Channels.ReliableDuplexSessionChannel.ProcessDuplexMessage(WsrmMessageInfo info) в System.ServiceModel.Channels.ReliableDuplexSessionChannel.HandleReceiveComplete(IAsyncResult результат) в System.ServiceModel.Channels.ReliableDuplexSessionChannel.OnReceiveCompletedStatic(IAsyncResult результат) в System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult результат) в System.Runtime.AsyncResult.Complete(Boolean завершено синхронно) при System.ServiceModel.Channels.ReliableChannelBinder 1.InputAsyncResult
1.OnInputComplete(IAsyncResult результат) в System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult результат) в System.Runtime.AsyncResult.Complete(Boolean завершено синхронно) при System.Runtime.InputQueue 1.AsyncQueueReader.Set(Item
item) at
System.Runtime.InputQueue
1.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
Сообщение: ссылка на объект не установлена экземпляр объекта.
StackTrace: при System.Web.HttpApplication.ThreadContext.Enter(Boolean setImpersonationContext) в System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext) в System.Web.AspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback обратный вызов, состояние объекта) в System.Web.AspNetSynchronizationContext.CallCallback(SendOrPostCallback обратный вызов, состояние объекта) в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4 (MessageRpc & RPC)
Ответы
Ответ 1
ОК - я нашел ответ. Очень странно, но просто поместите в класс оболочки обратного вызова WCF следующий атрибут:
[CallbackBehavior(UseSynchronizationContext=false)]
Спасибо Cauldwell.net за ответ: http://www.cauldwell.net/patrick/blog/CategoryView,category,CodeGen.aspx
От cauldwell.net:
Проблема, оказалось, заключалась в том, что ASP.NET использует (по умолчанию) немного это называется SynchronizationContext. Как близко, как я могу сказать (я не исследовал это тщательно, если честно), один из заданий, чтобы обратные вызовы запускаются в потоке пользовательского интерфейса, тем самым устраняя необходимость вызова Control.Invoke, как вы это делаете в WinForms. В моем случае это дополнительное замок давал что-то, и это пытался очистить нитки, которых уже не было вокруг, следовательно, к исключению NullReferenceException.