.NET 4.x HttpWebRequest.GetResponse не работает в потоке - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Написал класс для загрузки файлов с поддержкой простой докачки. Выглядит он вот так:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
 
namespace BlizzUpdateServerDownloader
{
    public class DownloadProgressChangedArgs
    {
        protected string filename;
        public string FileName
        {
            get { return filename; }
        }
 
        protected uint progress_percentage;
        public uint ProgressPercentage
        {
            get { return progress_percentage; }
        }
 
        public DownloadProgressChangedArgs(String Filename, uint Progress_percentage)
        {
            this.filename = Filename;
            this.progress_percentage = Progress_percentage;
        }
    }
    public class DownloadFileCompletedArgs
    {
        protected string filename;
        public string FileName
        {
            get { return filename; }
        }
 
        public DownloadFileCompletedArgs(String Filename)
        {
            this.filename = Filename;
        }
    }
    public class DownloadFileErrorArgs
    {
        protected string filename;
        protected Exception e;
        public string FileName
        {
            get { return filename; }
        }
        public Exception Error
        {
            get { return e; }
        }
 
        public DownloadFileErrorArgs(String Filename, Exception error)
        {
            this.filename = Filename;
            this.e = error;
        }
    }
 
    class InovationFileDownloader
    {
        public delegate void DownloadProgressChangedHandler(object sender, DownloadProgressChangedArgs e);
        public delegate void DownloadFileCompletedHandler(object sender, DownloadFileCompletedArgs e);
        public delegate void DownloadFileErrorHandler(object sender, DownloadFileErrorArgs e);
        public event DownloadProgressChangedHandler ProgressChanged;
        public event DownloadFileCompletedHandler FileCompleted;
        public event DownloadFileErrorHandler FileError;
 
        private const long fragment_size = 10 * 1024;
 
        private string url;
        private string filename;
        private long length;
        private long position;
        private long totalBytesRead;
 
        public long TotalBytesRead { get { return totalBytesRead; } }
        public long Length { get { return length; } }
        public long Position
        {
            get
            {
                return position;
            }
            set
            {
                if (value < 0) throw new ArgumentException();
                position = value;
            }
        }
        public InovationFileDownloader(string URL, string Filename)
        {
            url = URL;
            filename = Filename;
        }
 
        public void StartDownload()
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            HttpWebResponse result = (HttpWebResponse)request.GetResponse();
            length = result.ContentLength;
 
            using (FileStream fs = new FileStream(filename, FileMode.Append))
            {
                totalBytesRead = fs.Length;
                Position = fs.Length;
 
                while (TotalBytesRead < Length)
                {
                    try
                    {
                        int receivedLengh = 0;
                        if (TotalBytesRead + fragment_size < Length)
                            receivedLengh = (int)fragment_size;
                        else
                            receivedLengh = (int)(Length - TotalBytesRead);
 
                        byte[] buffer = new byte[receivedLengh];
                        int count = Read(buffer, 0, receivedLengh);
 
                        OnProgressChanged();
                        fs.Write(buffer, 0, count);
                    }
                    catch (Exception e)
                    {
                        OnFileError(e);
                    }
                }
 
                fs.Close();
            }
 
            OnDownloadComplete();
        }
 
        private int Read(byte[] buffer, int offset, int count)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.AddRange(Convert.ToInt32(position), Convert.ToInt32(position) + count);
            HttpWebResponse result = (HttpWebResponse)request.GetResponse();
 
            int readbytes = 0;
 
            using (Stream stream = result.GetResponseStream())
            {
                readbytes = stream.Read(buffer, offset, count);
                stream.Close();
            }
            result.Close();
            totalBytesRead += readbytes;
            Position += readbytes;
            return readbytes;
        }
 
        protected void OnProgressChanged()
        {
            if (ProgressChanged != null)
            {
                uint percents = (uint)((float)totalBytesRead / (float)Length * 100.0);
                ProgressChanged(this, new DownloadProgressChangedArgs(filename, percents));
            }
        }
 
        protected void OnDownloadComplete()
        {
            if (FileCompleted != null)
            {
                FileCompleted(this, new DownloadFileCompletedArgs(filename));
            }
        }
 
        protected void OnFileError(Exception e)
        {
            if (FileError != null)
            {
                FileError(this, new DownloadFileErrorArgs(filename, e));
            }
        }
    }
}
Когда я просто создаю объект этого класса и качаю какой-либо файл, то все идет нормально. Но стоит мне создать объект в потоке, и начать качать файл, то закачка не происходит. Зависает на GetResponse в методе Read, а после возвращает исключение с текстом: Время ожидания операции истекло. Вот так я создаю тред:
        void StartDownloadFile(object filename)
        {
            if (outputBox.InvokeRequired)
                this.outputBox.BeginInvoke(new Action(() => outputBox.AppendText("Start download " + (string)filename + "\r\n")));
            else
                outputBox.AppendText("Start download " + (string)filename + "\r\n");
 
            InovationFileDownloader iw = new InovationFileDownloader(base_path + (string)filename, (string)filename);
            iw.ProgressChanged += iw_ProgressChanged;
            iw.FileCompleted += iw_FileCompleted;
            iw.FileError += iw_FileError;
            iw.StartDownload();
        }
 
        void StartDownloadThread(string filename)
        {
            Thread t = new Thread(new ParameterizedThreadStart(StartDownloadFile));
            t.Start(filename);
            threadList.Add(t);
        }
Подскажите, что может быть не так?

Решение задачи: «.NET 4.x HttpWebRequest.GetResponse не работает в потоке»

textual
Листинг программы
public long Length { get; private set; }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4.667 из 5
Похожие ответы