Асинхронное скачивание файлов по очереди

Я написал метод асинхронного скачивания файлов по очереди, файлы берутся из листа. Также, есть показ скорости загрузки, процентов, размер файлов и размер скачавшихся файлов. Есть хостинг, с которого большие файлы не качаются через обычный 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, он работает по другому принципу. Помогите пожалуйста, как сделать все тоже самое что в моем методе в код, который скинул консультант. Буду очень благодарен.


Ответы (0 шт):