Pixel_Guy
@Pixel_Guy
C# программист разрабатывающий игры на unity

Почему WebClient не дозагружает некоторые файлы при использовании асинхронности?

Пишу приложение для загрузки большого количества картинок по ссылкам. Пользуюсь следующим кодом:
Parallel.ForEach<string>(LoadLinks, Link => LoadLink(Link));
...
static void LoadLink(string Link)
        {
            using (WebClient Client = new WebClient())
            {
                string OutFilePath = $"Result\\{DateTime.Now.Ticks}.jpg";
                Client.DownloadFileCompleted += Client_DownloadFileCompleted;

                try
                {                     
                    Client.DownloadFileTaskAsync(new Uri(Link), OutFilePath);
                }
                catch (Exception e) 
                {
                    Console.WriteLine(e.Message);
                }
}


Код исполняется и работает, но некоторые картинки после конца загрузки остаются битыми (не открываются), а некоторые загружаются не полностью (какая-то часть идет серой полосой, но разрешение как и должно быть).
607b47c3e474e149377876.png

При синхронном исполнении того же кода все сохраняется нормально.

Пробовал делать await/async ,но там получился тот же результат, поэтому я вернул все как было (да и насколько я понял это взаимозаменяемые технологии)
  • Вопрос задан
  • 129 просмотров
Решения вопроса 1
@vabka Куратор тега C#
Токсичный
async static Task Main(){
...

            foreach(string Link in LoadLinks)
            {
                await LoadLink(Link);
            }
}
async static Task LoadLink(string Link)
        {
            using (WebClient Client = new WebClient())
            {
                string OutFilePath = $"Result\\{DateTime.Now.Ticks}.jpg";
                Client.DownloadFileCompleted += Client_DownloadFileCompleted;

                try
                {                     
                    var Task = Client.DownloadFileTaskAsync(new Uri(Link), OutFilePath);
                }
                catch (Exception e) 
                {
                    Console.WriteLine(e.Message);
                }
}

Судя по вот этому коду - вы не дожидаетесь окончания загрузки, по тому сразу после создания таски клиент будет задиспозен и запрос отменится.
Чтобы всё заработало - надо сделать await
async static Task Main(){
...

            foreach(string Link in LoadLinks)
            {
                await LoadLink(Link);
            }
}
async static Task LoadLink(string Link)
        {
            using (WebClient Client = new WebClient())
            {
                string OutFilePath = $"Result\\{DateTime.Now.Ticks}.jpg";
                Client.DownloadFileCompleted += Client_DownloadFileCompleted;

                try
                {                     
                    await Client.DownloadFileTaskAsync(new Uri(Link), OutFilePath); // Вот тут
                }
                catch (Exception e) 
                {
                    Console.WriteLine(e.Message);
                }
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
BasiC2k
@BasiC2k
Для десктоп приложений количество одновременно открытых сокет подключений ограничено 4.
Чтобы увеличить это количество, в App.config нужно добавить секцию:

<system.net>
      <connectionManagement>
        <add address="*" maxconnection="200" />
      </connectionManagement>
 </system.net>


Описание:
https://docs.microsoft.com/en-us/dotnet/framework/...

Не утверждаю что причина в этом, но это нужно тоже учесть.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы