Ожидание полной загрузки файла webclient C#

123
04 февраля 2021, 00:20

Есть код, который скачивает список изображений по полученным ссылкам и конвертирует их для уменьшения размера:

 WebClient wcFastPic = new WebClient();
                wcFastPic.Headers.Add(HttpRequestHeader.Referer, urlImageFastPic);
                wcFastPic.DownloadFile(new Uri(screen), path + System.IO.Path.GetFileName(countScr + ".jpg"));
                wcFastPic.Dispose();
                using (MagickImage imageFastPic = new MagickImage(path + countScr + ".jpg"))
                {
                    MagickGeometry sizeIm = new MagickGeometry(imageFastPic.Width, imageFastPic.Height);
                    sizeIm.IgnoreAspectRatio = true;
                    imageFastPic.Quality = 70;
                    imageFastPic.Format = MagickFormat.Jpg;
                    imageFastPic.Resize(sizeIm);
                    imageFastPic.Write(path + countScr + ".jpg");
                    imageFastPic.Dispose();
                }

Из-за того, что на одном компьютере интернет медленный, иногда программа тупо зависает во время скачивания и приходится ее перезапускать. Чтобы решить эту проблему, решил добавить асинхронность, но прежде никогда с ней не работал (Ну и вообще не уверен, что это панацея). Посмотрев парочку статей и видосов на ютубе, у меня получился следующий общий метод для всех скачиваемых изображений:

 private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Form1 f1 = new Form1();
        f1.progressBar1.Value = e.ProgressPercentage;
    }
    async void DownloadFile(string urlFile, string filename, string refer)
    {
        WebClient webclient = new WebClient();
        await Task.Run(() =>
         {
             webclient.Headers.Add(HttpRequestHeader.Referer, refer);
             Form1 f1 = new Form1();
             webclient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
             webclient.DownloadFileAsync(new Uri(urlFile), filename);
             while (webclient.IsBusy) { }
             using (MagickImage imageFastPic = new MagickImage(filename))
             {
                 MagickGeometry sizeIm = new MagickGeometry(imageFastPic.Width, imageFastPic.Height);
                 sizeIm.IgnoreAspectRatio = true;
                 imageFastPic.Quality = 70;
                 imageFastPic.Format = MagickFormat.Jpg;
                 imageFastPic.Resize(sizeIm);
                 imageFastPic.Write(filename);
                 imageFastPic.Dispose();
             }
         });
    }

Основная проблема была дождаться конца загрузки изображения, использую для этого webclient.IsBusy. Вроде работает, но периодически программа все равно не докачивает 1-2 файла. Подскажите, что в этом коде исправить, чтобы она 100% работала правильно. Ну и, пожалуйста, подскажите как передать прогресс загрузки в progressBar, потому как вариант, написанный мной, не работает. Файлы на диске создаются одновременно, если судить по total commander, изначально у всех четырех вес 0кб. Затем они начинают скачиваться, но не всегда по порядку. Т.е. может скачаться 1, 2, а потом 4, и только после этого начнется загрузка 3. Но какой-то закономерности нет.

Вызываю это дело в следующем методе:

public void fastpic(string urlImageFastPic, int countScr, string path)
    {
        try
        {
            ParsingClass pc = new ParsingClass();
            HtmlAgilityPack.HtmlDocument HDImageFastPic = new HtmlAgilityPack.HtmlDocument();
            HDImageFastPic.LoadHtml(pc.connectionSite(urlImageFastPic));
            var screenChik = HDImageFastPic.DocumentNode.SelectSingleNode("//img[@id='image'][1]").GetAttributeValue("src", "");
            DownloadFile(screen, path + System.IO.Path.GetFileName(countScr + ".jpg"), urlImageFastPic);
        }
            catch (Exception ew)
            {
                MessageBox.Show("Ошибка FASTPIC: " + ew.Message);
            }
        }
    }

И уже на главной форме, при нажатии кнопки, вызываю этот метод для скачивания списка изображений

 //Скриншоты
        if (!checkBox2.Checked)
        {
            int jSc = 1;
            string[] listScreen = rutracker.ListScreenShots(html);
            foreach (var elem in listScreen)
            {
                if (listScreen[jSc - 1] != null)
                {
                        if (listScreen[0].Contains("fastpic")) downloadImage.fastpic(listScreen[jSc - 1], jSc, disk.Text);
                }
                jSc++;
            }
        }
READ ALSO
Как вывести объект C# в Unity консоль

Как вывести объект C# в Unity консоль

В PHP есть удобная функция var_dump, С# изучаю не долго, способы поиска не сработалиЕсть что-то подобное тут?

120
Замена типа в наследнике на производный тип

Замена типа в наследнике на производный тип

Допустим, есть дженерик-интерфейс(IRepository<T>) репозитория с типичными CRUD операциями

133
Как запустить ASP .NET Core проект на сервере с Ubuntu 16.04 и Apach?

Как запустить ASP .NET Core проект на сервере с Ubuntu 16.04 и Apach?

Всем приветДолго искал информацию по этому поводу, но так и не справился с этой задачей

113