.NET 4.x HttpWebRequest.GetResponse не работает в потоке - C#
Формулировка задачи:
Здравствуйте. Написал класс для загрузки файлов с поддержкой простой докачки. Выглядит он вот так:
Когда я просто создаю объект этого класса и качаю какой-либо файл, то все идет нормально. Но стоит мне создать объект в потоке, и начать качать файл, то закачка не происходит. Зависает на GetResponse в методе Read, а после возвращает исключение с текстом: Время ожидания операции истекло.
Вот так я создаю тред:
Подскажите, что может быть не так?
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));
}
}
}
} 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; }