Асинхронное скачивание файлов по очереди
Я написал метод асинхронного скачивания файлов по очереди, файлы берутся из листа. Также, есть показ скорости загрузки, процентов, размер файлов и размер скачавшихся файлов. Есть хостинг, с которого большие файлы не качаются через обычный DownloadFile. Ошибка "Неожиданный EOF или 0 байт из транспортного потока." DownloadFile("ссылка", @"куда качать"); - вот это не работает с большими файлами, больше в коде ничего нет. Очень много гуглил - бесполезно, чего только не делал. Написал консультанту на хостинге, он отправил сообщение системному администратору, попросили прислать StackTrace - прислал. Ждал ночь. В итоге написали мне мол проблему решить не удалось, можем посоветовать использовать поддержку докачки файлов. И дал мне такой код:
private void DownloadFile()
{
string sSourceURL = "файл на сервере";
string sDestinationPath = @"D:\file.gz";
long iFileSize = 0;
int iBufferSize = 1024;
iBufferSize *= 1000;
long iExistLen = 0;
FileStream saveFileStream;
if (File.Exists(sDestinationPath))
{
FileInfo fINfo = new FileInfo(sDestinationPath);
iExistLen = fINfo.Length;
}
if (iExistLen > 0)
saveFileStream = new FileStream(sDestinationPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
else
saveFileStream = new FileStream(sDestinationPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
HttpWebRequest hwRq;
HttpWebResponse hwRes;
hwRq = (HttpWebRequest)HttpWebRequest.Create(sSourceURL);
hwRq.AddRange((int)iExistLen);
Stream smRespStream;
hwRes = (HttpWebResponse)hwRq.GetResponse();
smRespStream = hwRes.GetResponseStream();
iFileSize = hwRes.ContentLength;
int iByteSize;
byte[] downBuffer = new byte[iBufferSize];
while ((iByteSize = smRespStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
saveFileStream.Write(downBuffer, 0, iByteSize);
}
saveFileStream.Close();
}
И о чудо! Я вставил ссылку и файл скачался, при чем теперь можно закрывать программу, открыть ее заново и файл начнет качание не заново, он докачает столько, сколько не докачал. Но мне нужно узнавать постоянно размер скачавшихся файлов, скорость скачивания и нужна пауза. Вот мой код, в котором это все есть: Лишнее убрал, чтобы было поменьше, оставил самое важное.
public static async void DownloadFiles(IEnumerable<string> exfiles) // Ассинхронное скачивание файлов один за одним
{
App.MW.Stop = false;
Stopwatch sw = new Stopwatch();
string DownloadFile = "";
try
{
double size = 0; // Размер всех файлов
double downloaded_tmp = 0; // Сколько байт скачивающегося файла уже скачалось
double downloaded = 0; // Сколько байт из всех файлов скачалось
int progress = 0; // Процент скачавшихся данных (0-100)
foreach (var file in exfiles) // Проходим по списку и получаем размер всех файлов
{
size += GetFileSize(new Uri("https://site" + file));
}
using (var http = new WebClient())
{
http.DownloadProgressChanged += (s, e) =>
{
if (App.MW.Stop == true)
{
http.Dispose();
http.CancelAsync();
}
else
{
downloaded_tmp = e.BytesReceived; // Сколько байт от скачивающегося файла скачалось
progress = (int)((downloaded + downloaded_tmp) / size * 100); // Получаем процент скачавшихся данных
App.MW.Dispatcher.Invoke(() =>
{
App.MW.DownloadBar.Value = progress;
App.MW.DownloadLabel2.Content = Math.Round((size / 1073741824)*progress/100, 3) + "гб из " + Math.Round(size / 1073741824, 3) + "гб";
var speed = Math.Round(e.BytesReceived / 1024 / sw.Elapsed.TotalSeconds);
App.MW.DownloadLabel.Content = progress + " % (" + Math.Round(speed / 1024, 3) + "мб/сек)";
});
if (progress == 100 || size * progress / 100 == size || size * progress / 100 > size)
{
MessageBox.Show("готово");
}
}
};
http.DownloadFileCompleted += (s, e) => {
downloaded += downloaded_tmp;
};
foreach (var file in exfiles)
{
if (App.MW.Stop == true)
{
await App.MW.Dispatcher.BeginInvoke(new Action(delegate ()
{
MessageBox.Show("загрузка остановлена");
}));
}
else
{
DownloadFile = file;
await App.MW.Dispatcher.BeginInvoke(new Action(delegate ()
{
App.MW.filesStatusLabel.Text = file;
}));
try
{
sw.Start();
await http.DownloadFileTaskAsync(new Uri("сайт" + file), file);
}
catch { }
}
}
}
}
catch (Exception E) { MessageBox.Show(E.ToString()); }
}
Код, который скинул консультант, там же даже нет DownloadFile, он работает по другому принципу. Помогите пожалуйста, как сделать все тоже самое что в моем методе в код, который скинул консультант. Буду очень благодарен.