Hi We have noticed on our production server an extremely rare race condition with HttpWebRequest that is causing our application to crash from time to time.
The race condition is caused when HttpWebRequest is used in async mode and the Abort method.
In some critical points calling the abort method can cause a background thread (not under our control) to get an unhandled exception with the following stack trace:
Unhandled Exception: System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success
)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolea
n& success)
at System.Net.UnsafeNclNativeMethods.OSSOCK.setsockopt(SafeCloseSocket socket
Handle, SocketOptionLevel optionLevel, SocketOptionName optionName, Int32& optio
nValue, Int32 optionLength)
at System.Net.Sockets.Socket.SetSocketOption(SocketOptionLevel optionLevel, S
ocketOptionName optionName, Int32 optionValue, Boolean silent)
at System.Net.Sockets.NetworkStream.SetSocketTimeoutOption(SocketShutdown mod
e, Int32 timeout, Boolean silent)
at System.Net.ConnectStream.DrainSocket()
at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean abort
ing)
at System.Net.ConnectStream.System.Net.ICloseEx.CloseEx(CloseExState closeSta
te)
at System.Net.HttpWebRequest.SetAndOrProcessResponse(Object responseOrExcepti
on)
at System.Net.ConnectionReturnResult.SetResponses(ConnectionReturnResult retu
rnResult)
at System.Net.Connection.ReadComplete(Int32 bytesRead, WebExceptionStatus err
orStatus)
at System.Net.Connection.ReadCallback(IAsyncResult asyncResult)
at System.Net.Connection.ReadCallbackWrapper(IAsyncResult asyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr u
serToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32
errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32
errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
as you can the thread is a system thread dealing with the async IO. After some tests we managed to reproduce the rare crash easily with the following code: (The code launches many http requests and cancels them after a random period of time)
while ( true ){
var req = HttpWebRequest.Create("http://www.amazon.com?s=" + i ) as HttpWebRequest;
var ares =
req.BeginGetResponse((res) =>
{
try
{
var resp = req.EndGetResponse(res);
new StreamReader(resp.GetResponseStream()).ReadToEnd();
resp.Dispose();
}
catch
{
}
},null);
Timer timer = null;
timer =
new Timer((o) =>
{
try
{
req.Abort();
}
catch
{
}
timer.Dispose();
}, null, rnd.Next(0, 1200), System.Threading.Timeout.Infinite);
tm.Add(timer);
}
Any ideas?