Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.65/48: Рейтинг темы: голосов - 48, средняя оценка - 4.65
3 / 3 / 3
Регистрация: 30.09.2014
Сообщений: 79
1
.NET 4.x

Как скачивать несколько файлов через WebClient по очереди, через DownloadFileAsync

17.02.2016, 00:11. Показов 9641. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброй ночи. Столкнулся с проблемой по скачиванию нескольких файлов друг за другом.
Фулл код как скачиваю:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void DownloadMPQ(Uri u, string s)
        {
            WebClient web = new WebClient();
            web.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Download);
            web.DownloadFileCompleted += new AsyncCompletedEventHandler(DownComp);
            web.DownloadFileAsync(u, s);
        }
        void DownComp(object sender, AsyncCompletedEventArgs e)
        {
            NotificShow(String.Format("'{0}' скачан.", ThisFile));
        }
        void Download(object sender, DownloadProgressChangedEventArgs e)
        {
            long q = e.TotalBytesToReceive / 1024;
            prgDownload.Properties.Maximum = (int)q;
            prgDownload.EditValue = e.BytesReceived / 1024;
        }
И как вызываю (на примере 1 файла)
C#
1
DownloadMPQ(new Uri("http://localhost/mp.mpq"), "mp.mpq");
В итоге он мне начинает качать все файлы подряд, т.е. в несколько потоков.
Вопрос все таки такой: как мне дождаться скачивания 1 файла и начать качать 2й? Новый поток? Пробовал. Не двигается прогресс бар.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.02.2016, 00:11
Ответы с готовыми решениями:

WebClient. Как правильно скачивать несколько файлов асинхронно?
Подскажите как правильно скачивать несколько файлов асинхронно? сейчас для каждого файла свой...

Асинхронная загрузка файлов методом WebClient.DownloadFileAsync
Вопрос адресуется в первую очередь профессионалам. При разработке приложения возникла...

Ссылки для скачивания с помощью WebClient.DownloadFile и WebClient.DownloadFileAsync
Ссылки какие должны быть, для скачивания webClient.DownloadFile и webClient.DownloadFileAsync Не...

Цикличная загрузка файлов через webclient
Есть у меня интересный код обновы,где всё что надо обновить качается в цикле. Загрузка идёт по...

22
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
17.02.2016, 08:28 2
Лучший ответ Сообщение было отмечено LiptoN-Mmo-Dev как решение

Решение

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        public async Task DownloadManyFiles(Dictionary<Uri, string> files)
        {
            WebClient wc = new WebClient();
            wc.DownloadProgressChanged += (s, e) => progressBar1.Value = e.ProgressPercentage;
            foreach (KeyValuePair<Uri, string> pair in files) { await wc.DownloadFileTaskAsync(pair.Key,pair.Value);}
            wc.Dispose();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Dictionary<Uri, string> dict = new Dictionary<Uri, string>();
            dict.Add(new Uri("https://download.microsoft.com/download/4/E/3/4E38FD5A-8859-446F-8C58-9FC70FE82BB1/Express%2032BIT%20WoW64/SQLEXPR32_x86_RUS.exe"), "Firstfile.exe");
            dict.Add(new Uri("https://download.microsoft.com/download/4/E/3/4E38FD5A-8859-446F-8C58-9FC70FE82BB1/Express%2032BIT/SQLEXPR_x86_RUS.exe"), "Secondfile.exe");
            DownloadManyFiles(dict);
        }
Попробуйте так.
3
3 / 3 / 3
Регистрация: 30.09.2014
Сообщений: 79
18.02.2016, 19:59  [ТС] 3
EvilFromHell громадное спасибо!!!!!!! Работает!
0
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
03.05.2016, 21:21 4
Доброго времени суток!
Цитата Сообщение от EvilFromHell Посмотреть сообщение
public async Task DownloadManyFiles(Dictionary<Uri, string> files)
в этом месте ошибка: Не все ветви кода возвращают значение.

Подскажите что не так делаю.
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
03.05.2016, 21:35 5
Hoffman, приведите проблемный код полностью. Сами по себе методы, приведенные выше, не могут не работать.
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
03.05.2016, 22:04 6
Цитата Сообщение от EvilFromHell Посмотреть сообщение
C#
1
2
3
4
5
6
7
public async Task DownloadManyFiles(Dictionary<Uri, string> files)
{
    WebClient wc = new WebClient();
    wc.DownloadProgressChanged += (s, e) => progressBar1.Value = e.ProgressPercentage;
    foreach (KeyValuePair<Uri, string> pair in files) { await wc.DownloadFileTaskAsync(pair.Key,pair.Value);}
    wc.Dispose();
}
Просто вставил к себе в код. Task DownloadManyFiles подчеркнуто красным, при наведении мыши всплывает подсказка с текстом "Не все ветви кода возвращают значение"

Я понимаю о чем говорит эта ошибка но не знаю как исправить так как не знаю что должен вернуть этот метод (и вообще должен ли)

Код
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public void UpdateProgram()
        {
            int countFile = GetFileList();
            
            for (int i = 0; i < countFile; i++)
            {
                try
                {
                    //WebClient client = new WebClient();
                    //client.DownloadProgressChanged += Client_DownloadProgressChanged;
                    //client.DownloadFileCompleted += Client_DownloadFileCompleted;
                    //client.DownloadFileAsync(new Uri(@"" + upHost + @"\Update" + list_files[i]), list_files[i]+"_new");
 
                    Dictionary<Uri, string> dict = new Dictionary<Uri, string>();
                    dict.Add(new Uri("https://download.microsoft.com/download/4/E/3/4E38FD5A-8859-446F-8C58-9FC70FE82BB1/Express%2032BIT%20WoW64/SQLEXPR32_x86_RUS.exe"), "Firstfile.exe");
                    dict.Add(new Uri("https://download.microsoft.com/download/4/E/3/4E38FD5A-8859-446F-8C58-9FC70FE82BB1/Express%2032BIT/SQLEXPR_x86_RUS.exe"), "Secondfile.exe");
                    DownloadManyFiles(dict);
 
                    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }
        public async Task DownloadManyFiles(Dictionary<Uri, string> files)
        {
            WebClient wc = new WebClient();
            wc.DownloadProgressChanged += (s, e) => prbUpdate.Value = e.ProgressPercentage;
            foreach (KeyValuePair<Uri, string> pair in files) { await wc.DownloadFileTaskAsync(pair.Key, pair.Value); }
            wc.Dispose();
        }
 
        private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            prbUpdate.Maximum = (int)e.TotalBytesToReceive / 100;
            prbUpdate.Value = (int)e.BytesReceived / 100;
        }
 
        private void Client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //MessageBox.Show("Готово");
            btnUpdateOK.Enabled = true;
            lblUpdate.Text = "Загрузка завершена";
            lblUpdate1.Text = "Нажмите ОК для применения изменений";
            lblUpdate.ForeColor = Color.Red;
            lblUpdate1.ForeColor = Color.Red;
        }
 
        private void Form1_Shown(object sender, EventArgs e)
        {
            UpdateProgram();
        }
Добавлено через 21 минуту
EvilFromHell, уже вижу что затупил.
Исправил так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        public void UpdateProgram()
        {
           //int countFile = GetFileList();
            Dictionary<Uri, string> dict = new Dictionary<Uri, string>();
            dict.Add(new Uri("https://download.microsoft.com/download/4/E/3/4E38FD5A-8859-446F-8C58-9FC70FE82BB1/Express%2032BIT%20WoW64/SQLEXPR32_x86_RUS.exe"), "Firstfile.exe");
            dict.Add(new Uri("https://download.microsoft.com/download/4/E/3/4E38FD5A-8859-446F-8C58-9FC70FE82BB1/Express%2032BIT/SQLEXPR_x86_RUS.exe"), "Secondfile.exe");
            DownloadManyFiles(dict);
        }
        public async Task DownloadManyFiles(Dictionary<Uri, string> files)
        {
            WebClient wc = new WebClient();
            wc.DownloadProgressChanged += (s, e) => prbUpdate.Value = e.ProgressPercentage;
            foreach (KeyValuePair<Uri, string> pair in files) { await wc.DownloadFileTaskAsync(pair.Key, pair.Value); }
            wc.Dispose();
        }
не помогло.
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
03.05.2016, 23:00 7
Я что-то пока вообще не понимаю как вы умудряетесь получать такой результат... можете проект скинуть?
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
03.05.2016, 23:06 8
Цитата Сообщение от EvilFromHell Посмотреть сообщение
можете проект скинуть?
Updater.7z
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
03.05.2016, 23:19 9
Hoffman, у вас не подключено пространство имен
C#
1
using System.Threading.Tasks;
И стоит старая версия .NET. Поставьте от 4.5.
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
03.05.2016, 23:30 10
Цитата Сообщение от EvilFromHell Посмотреть сообщение
И стоит старая версия .NET. Поставьте от 4.5.
Вот с этим как раз проблема... Нужно именно для .NET 4.

Собственно меня почти устраивает обычный метод скачивания:
C#
1
2
3
4
WebClient client = new WebClient();
client.DownloadProgressChanged += Client_DownloadProgressChanged;
client.DownloadFileCompleted += Client_DownloadFileCompleted;
client.DownloadFileAsync(new Uri(@"" + upHost + @"\Update" + list_files[i]), list_files[i]+"_new");
так как файлы качаются не большие и их не много (глюки progressbar'a не особо заметны) но не могу никак отловить окончание скачивания всех файлов. И все-таки хотелось бы сделать по человечески. Может есть какой-нибудь альтернативный способ? Буду очень благодарен за помощь.
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
03.05.2016, 23:41 11
Hoffman, тогда вам придется использовать событие DownloadFileCompleted у WebClient. Конечно, это будет выглядеть уродливо и длинно по сравнению с текущим вариантом. Лучше использовать нормальный .NET.
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
03.05.2016, 23:45 12
Цитата Сообщение от EvilFromHell Посмотреть сообщение
придется использовать событие DownloadFileCompleted у WebClient
Я им и пытаюсь воспользоваться, только он срабатывает по окончании загрузки самого маленького файла.
Можно попросить у вас пример кода?
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
04.05.2016, 00:01 13
Hoffman, попробуйте вместо
C#
1
await wc.DownloadFileTaskAsync(pair.Key, pair.Value);
Использовать вот такой метод:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static class WVExtesions
{
    public static Task WaitForLoadingComplete(this WebClient client, Uri Uri, string filename)
    {
        var tcs = new TaskCompletionSource<bool>();
        AsyncCompletedEventHandler handler = ((sender, e) => tcs.TrySetResult(true));
        client.DownloadFileCompleted += handler;
        client.DownloadFileAsync(Uri, filename);
        tcs.Task.ContinueWith(_ =>
        {
            client.DownloadFileCompleted -= handler;
        }, TaskContinuationOptions.ExecuteSynchronously);
        return tcs.Task;
    }
}
По смыслу он должен быть аналогичен, если я ничего не напутал. Код не проверял.
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
04.05.2016, 14:41 14
EvilFromHell, можно еще немного тупых вопросов...))
Если правильно понял заменяем
C#
1
await wc.DownloadFileTaskAsync(pair.Key, pair.Value);
вызовом метода:
C#
1
2
3
4
5
6
7
8
9
10
11
public async Task DownloadManyFiles(Dictionary<Uri, string> files)
{
  WebClient wc = new WebClient();
  wc.DownloadProgressChanged += (s, e) => prbUpdate.Value = e.ProgressPercentage;
  foreach (KeyValuePair<Uri, string> pair in files)
  {
    //await wc.DownloadFileTaskAsync(pair.Key, pair.Value);
    WaitForLoadingComplete(...,...,...);
  }
  wc.Dispose();
}
Так?
И еще вопрос. Что в параметрах должно быть указано в данном случае при вызове метода?
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
04.05.2016, 21:17 15
Hoffman, я же написал, использовать так же, как DownloadFileTaskAsync. Параметры, как прекрасно видно, те же.
C#
1
await wc.WaitForLoadingComplete(pair.Key, pair.Value);
0
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
04.05.2016, 21:44 16
EvilFromHell, к сожалению
C#
1
await wc.WaitForLoadingComplete(pair.Key, pair.Value);
тоже для .NET 4.5

В любом случае спасибо огромное за помощь. Буду пытаться как-то выбить из начальства .NET 4.5
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
04.05.2016, 21:47 17
Hoffman, неправда. Все классы, которые используются в этом методе, есть и в .NET 4, я проверял.
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
04.05.2016, 21:52 18
Цитата Сообщение от EvilFromHell Посмотреть сообщение
Hoffman, неправда.
Выбрана версия .Net 4:
Как скачивать несколько файлов через WebClient по очереди, через DownloadFileAsync

Если выбрать версию 5 то все нормально.
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
04.05.2016, 22:14 19
Hoffman, естественно так не будет работать, почитайте, что такое методы расширения. Объявлен он должен быть именно так, как я показал выше. То есть в статическом классе.
1
1 / 1 / 2
Регистрация: 04.08.2014
Сообщений: 71
04.05.2016, 22:23 20
EvilFromHell, спасибо за помощь, буду читать, разбираться.
0
04.05.2016, 22:23
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.05.2016, 22:23
Помогаю со студенческими работами здесь

Загрузка файлов через WebClient с отображением процентов
Здравствуйте, не очень понимаю, как сделать вывод процентов загрузки. Хочу сделать ProgressBar на...

Загрузка файлов с другого компьютера через WebClient
Здравствуйте, форумчане, помогите решить проблему. Есть функция, которая загружает файл по нажатию...

WebClient.DownloadFileAsync и WebClient.DownloadFile
Если правильно понимаю, то WebClient.DownloadFileAsync и WebClient.DownloadFile это 2 разных...

Запустить через один sh несколько sh по очереди
Помогите разобраться каким образом используя один sh запускать через него несколько sh по очереди


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru