ObjectDisposedException System.Threading.Timer.throwIfDisposed () получающий брошенный - PullRequest
1 голос
/ 22 февраля 2011

Я получаю ужасное исключение и 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

Я загружаю HTML в отдельном потоке, и иногда мне нужно прервать этот поток, но я вызываю Join, чтобы это не было большой проблемой, верно?

Есть ли способ поймать это исключение или его не выбросить? Или есть какой-нибудь способ, которым я могу найти точно, откуда он был брошен (какой экземпляр HttpWebRequest или какой объект бросает это)

EDIT:

Хорошо, еще немного о том, что происходит. Я делаю 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 Ответ

3 голосов
/ 22 февраля 2011

Прерывание потока приводит к тому, что любые [не общие] ссылочные объекты автоматически удаляются (если этим объектом реализовано IDisposable). Есть таймер, который настроен на то, чтобы что-то делать через определенные промежутки времени (кажется, что происходит некоторая асинхронная сетевая активность). Удаление потока привело к тому, что таймер был удален, и это является причиной исключения.

Попробуйте вызвать соответствующий метод отключения вместо прерывания потока. Как правило, никогда не прерывайте поток, если вы не уверены, где он находится и каковы последствия того, что он не сможет завершить свою работу. Для более точного обсуждения вашего дела требуется больше деталей.

...