Как видно из названия, я, кажется, получаю ObjectDisposedException
при вызове "Abort"
на HttpWebRequest
, используемом асинхронно (то есть BeginGetResponse
), и не могу, на мой взгляд, понять, как предотвратить это. Я потратил весь день на поиски решения, поэтому любая помощь будет оценена. Вот простой пример, иллюстрирующий проблему:
// helper class that gets passed through as the state
class RequestState
{
public HttpWebRequest Request { get; set; }
public bool TimedOut { get; set; }
}
class Program
{
static void Main(string[] args)
{
var rs = new RequestState
{
Request = (HttpWebRequest)WebRequest.Create("http://google.com")
};
var result = rs.Request.BeginGetResponse(
asyncResult =>
{
if (asyncResult.IsCompleted)
{
var reqState = asyncResult.AsyncState as RequestState;
if (reqState != null && !reqState.TimedOut)
{
using (var response = reqState.Request.EndGetResponse(asyncResult) as HttpWebResponse)
{
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
Console.WriteLine(streamReader.ReadToEnd());
}
}
}
else
{
Console.WriteLine("Timed out!");
}
}
},
rs);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle,
(state, timeout) =>
{
if (timeout)
{
var temprs = state as RequestState;
if (temprs != null)
{
// set TimedOut flag
temprs.TimedOut = true;
// this will cause the BeginGetResponse callback above to be called
temprs.Request.Abort();
}
// after this method leaves scope the ObjectDisposedException occurs!
}
},
// time out of 7 seconds
rs, 7000, true);
Console.ReadLine();
}
}
Вот что я делаю:
Если я запускаю это нормально, ответ записывается в консоль просто отлично. Однако, если я использую Fiddler для имитации медленного интернет-соединения (или практически без соединения) и выполняется обратный вызов тайм-аута, я получаю вышеупомянутый ObjectDisposedException
(хотя "Timed out!"
сначала записывается в консоль). Я не получу это исключение, если я не позвоню Abort
на HttpWebRequest
.
Может кто-нибудь сказать мне, что я делаю не так? Я нацеливаюсь на .NET 3.5 framework. Заранее благодарю за любое просветление.
Вот информация об исключении / стек вызовов:
System.ObjectDisposedException occurred
Message=Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
Source=System
ObjectName=System.Net.Sockets.NetworkStream
StackTrace:
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
InnerException:
System.Net.Sockets.NetworkStream.EndRead(System.IAsyncResult asyncResult) + 0x1b7 bytes
System.Net.PooledStream.EndRead(System.IAsyncResult asyncResult) + 0x10 bytes
System.Net.Connection.ReadCallback(System.IAsyncResult asyncResult) + 0x33 bytes
System.Net.Connection.ReadCallbackWrapper(System.IAsyncResult asyncResult) + 0x46 bytes
System.Net.LazyAsyncResult.Complete(System.IntPtr userToken) + 0x69 bytes
System.Net.ContextAwareResult.Complete(System.IntPtr userToken) + 0xab bytes
System.Net.LazyAsyncResult.ProtectedInvokeCallback(object result, System.IntPtr userToken) + 0xb0 bytes
System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* nativeOverlapped) + 0x94 bytes
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x54 bytes