ObjectDisposedException при вызове Abort для HttpWebRequest, используемого асинхронно

Как видно из заголовка, я, кажется, получаю 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. Заранее благодарен за любое просветление.

Вот информация об исключении/стек вызовов:

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

person dreyln    schedule 14.12.2010    source источник
comment
Поскольку вы все равно используете замыкания, в AsyncState нет смысла.   -  person SLaks    schedule 14.12.2010
comment
Да это правда. Когда я изначально кодировал это, у меня были обратные вызовы как именованные методы, но я не удосужился сделать это, когда собрал короткий пример кода, чтобы проиллюстрировать проблему. Я опубликую трассировку стека завтра, когда вернусь к работе. Спасибо   -  person dreyln    schedule 16.12.2010
comment
Эта проблема возникает, когда я использую System.Net.Http.HttpClient, который использует HttpWebRequest. Это может быть причиной плохой ненадежности, когда URL-адрес неверный. Я написал об этом: stackoverflow.com/questions/19868292/   -  person Elliot    schedule 15.11.2013
comment
Это все еще происходит, у меня есть частичная работа вокруг stackoverflow.com/questions/23532249/   -  person Matt    schedule 08.05.2014