Assume that:
- An ASP.NET MVC3 Page (using visual studio debug server) calls a WCF Service (self hosted, net.tcp binding).
- Service uses ThreadPool to do some work, but returns immediately a value to the client
- Client gets the value and redirects to another page.
- A few seconds later the Server crashes with an “ObjectDisposedException / Safe handle has been released)
First I thought that the proxy would be disposed after the page redirect and the wcf service would get disposed too, but even when I’m not using the ThreadPool (by calling the method within the wcf service thread) I get the exception too. I don’t get it.
I’m not really into web programming. What am I doing wrong?
Client
Global.asax (registering channel factory)
protected void Application_Start()
{
builder.Register(c => new ChannelFactory<IWcfBakeryService >("")).SingleInstance();
builder.Register(c => c.Resolve<ChannelFactory<IWcfBakeryService>>()
.CreateChannel())
.UseWcfSafeRelease();
}
Repository (channel injected by Autofac)
public BakeryRepository(IWcfBakeryService orderService)
{
}
public ReciepeResponse RequestReciepe(CakeDto webOrder)
{
[...]
return service.RequestReciepe(request);
}
Server:
Contract
[ProtoBehavior, OperationContract(IsTerminating=false)]
ReciepeResponse RequestReciepe(ReciepeRequest request);
Service-Implementation
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
RequestReciepe / Service Method
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork));
return new ReciepeResponse() { SomeValue = "Some Value"};
Exception Stacktrace (catched by AppDomain UnhandledException)
bei System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
bei System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
bei Microsoft.Win32.Win32Native.SetEvent(SafeWaitHandle handle)
bei System.Threading.EventWaitHandle.Set()
bei System.Runtime.Remoting.Messaging.AsyncResult.SyncProcessMessage(IMessage msg)
bei System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
bei System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.DoAsyncCall()
bei System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(Object o)
bei System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
bei System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
bei System.Threading.ThreadPoolWorkQueue.Dispatch()
bei System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
Solved.
My Wcf Service uses existing business logic. Another developer used an implementation of an custom Parallel class for multithreading purposes, which was calling:
The Method who used the Parallel class wasn’t designed thread-safe. After doing this, everything seems to work fine.