ObjectDisposedException System.Threading.Timer.throwIfDisposed()被抛出

时间:2011-02-22 02:05:00

标签: c# exception exception-handling httpwebrequest

我得到一个可怕的异常抛出和IDK如何解决它:(

System.ObjectDisposedException 
ObjectDisposedException-   at System.Threading.Timer.throwIfDisposed()
   at System.Threading.Timer.Change(UInt32 dueTime, UInt32 period)
   at System.Threading.Timer.Change(Int32 dueTime, Int32 period)
   at System.Net.HttpWebRequest.ConnectionClient.Read(Byte[] data, Int32 offset, Int32 length)
   at System.Net.HttpReadStream.NetworkRead(Byte[] data, Int32 offset, Int32 length)
   at System.Net.ContentLengthReadStream.doRead(Byte[] data, Int32 offset, Int32 length)
   at System.Net.HttpReadStream.ReadToDrain(Byte[] buffer, Int32 offset, Int32 length)
   at System.Net.HttpReadStream.doClose()
   at System.Net.ContentLengthReadStream.doClose()
   at System.Net.HttpReadStream.Finalize()

我已经读过,当您尝试重用HttpWebRequest或类似的东西时会发生这种情况,但我已经对整个项目进行了两次和三次检查,而且我没有重复使用任何HttpWebRequest < / p>

我在单独的线程上下载HTML,有时我需要中止该线程,但是我打电话给Join这样不应该是一个大问题吗?

有没有办法捕获此异常或不抛出它?或者有什么方法可以找到它被抛出的确切位置(HttpWebRequest的哪个实例或者任何对象抛出它)

编辑:

好的,关于发生了什么事情。我正在对UI上的不同线程进行HttpWebRequest调用(像大多数人一样)但是当我关闭应用程序时,它会挂起,因为HTTP请求没有成功或超时。所以我决定放弃他们(这么暴力的一句话,你不觉得吗?)那是异议何时开始发生的。如果有更好的方法可以做到这一点,我都是耳朵!

这是我正在调用的方法之一,有时会被中断。我运行它直到最多有6个线程:

private static void startImageDownloading()
{
    ThreadStart start = () =>
    {
        while (_list.Count > 0) // _list contains all of the images that need to be downloaded
        {
            ImageRequest req; // ImageRequests are containers that hold all the request info
            lock (_list)
            {
                if (_list.Count > 0)
                    req = _list.Dequeue();
                else continue;
            }

            if (req.Item.Parent.IsDisposed)
                continue;

            using (MemoryStream i = getImageWeb(req))
                if (i != null)
                {
                    foreach (var callback in req.Callbacks)
                        callback(i);    //  Callbacks is a List<ImageDelegate> object

                    if (req.Item.Parent != null && !req.Item.Parent.IsDisposed)
                        req.Item.Parent.Damage();   //  Cross thread Invalidate call
                }
        }

        Thread.CurrentThread.Priority = ThreadPriority.Lowest;
    };

    Thread t = new Thread(start) { IsBackground = true, Priority = ThreadPriority.BelowNormal };

    t.Start();

    _downloadThreads.Add(t);
}

这是getImageWeb:

private static MemoryStream getImageWeb(ImageRequest req)
{
    int tries = 0;
    try
    {
        MemoryStream ret = null;
        while (tries < maxRetries && (ret = downloadImageFile(req.Uri)) == null && !req.Cancelled)
            tries++;

        return ret;
    }
    catch { }

    return null;
}

最后下载ImageFile:

private static MemoryStream downloadImageFile(string url)
{
    MemoryStream ret = null;

    try
    {
        var uri = new Uri(url);

        var webRequest = (HttpWebRequest)WebRequest.Create(uri);
        webRequest.Method = "GET";
        webRequest.Timeout = 10000;
        webRequest.ProtocolVersion = HttpVersion.Version10;
        webRequest.Proxy = null;
        using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
        {
            if (webResponse.StatusCode.ToString().Equals("OK"))
            {
                ret = new MemoryStream();
                using (Stream responseStream = webResponse.GetResponseStream())
                {
                    if (responseStream == null)
                        return null;
                    CopyStream(responseStream, ret);
                }
                ret.Position = 0;
            }
        }
    }
    catch (WebException e)
    {
        string error = "";
        if (e.Response != null)
            using (var response = e.Response)
            using (var resp = response.GetResponseStream())
            using (var errorStream = new StreamReader(resp))
                error = errorStream.ReadToEnd();
    }
    catch (Exception exp)
    {
    }

    return ret;
}

1 个答案:

答案 0 :(得分:3)

中止线程会导致任何[非共享]引用对象自动处理(如果该对象实现了IDisposable)。有一个计时器,配置为间隔执行某些操作(似乎是一些异步网络活动)。删除该线程导致该计时器被处理,这是异常的原因。

尝试调用适当的断开连接方法,而不是中止线程。作为一般规则,永远不要中止线程,除非你确定它在哪里以及阻止它完成工作的后果是什么。需要更多细节来更准确地谈论您的案例。