We have a production issue that is crashing the IIS application pool for a .NET 4.8 application. The EventViewer shows the application pool crashing and a corresponding error:
An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/3/ROOT
Process ID: 18864 Exception: System.ObjectDisposedException Message: Safe handle has been closed
StackTrace: at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success) at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success) at Microsoft.Win32.Win32Native.SetEvent(SafeWaitHandle handle) at System.Threading.EventWaitHandle.Set() at System.Runtime.Remoting.Messaging.AsyncResult.SyncProcessMessage(IMessage msg) at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() at System.Threading.ThreadPoolWorkQueue.Dispatch()
I believe it is related to the use of IAsyncResult given the AsyncProcessMessage and the application has only 1 usage but nothing jumps out. I've used DebugDiag which didn't reveal any additional details.
var swTimer = Stopwatch.StartNew();
AsyncMethodCaller caller = new AsyncMethodCaller(myProg.DoWork);
IAsyncResult delegateResult = caller.BeginInvoke();
while (delegateResult.IsCompleted == false)
{
Thread.Sleep(100);
if (swTimer.ElapsedMilliseconds > 50000)
{
logger.LogTrace("Long Running Process");
// Update DB with status
swTimer.Restart();
}
}
result = caller.EndInvoke(delegateResult);
delegateResult.AsyncWaitHandle.Close();
I try to reproduce the issue according to the code you provide but failed. So I'm not sure if the issue was caused by above code. How did you know for sure?
However, I find something strange in the code.
When you use BeginInvoke() to call the delegate mthod, you need to pass two paramters at least
AsyncCallback
andobject
, even though the synchronous method does not need to pass in any parameters.Why you call
WaitHandle.Close
to release resource while there's no call ofAsyncWaitHandle
property? Only when you useto wait a singal from caller, you need to close it for release resource.
Waiting for an Asynchronous Call with WaitHandle
I'm not sure what code it is. But if you use thread of caller to update DB, this may causes thread blocking and your issue.