Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/10: Рейтинг темы: голосов - 10, средняя оценка - 4.50
natrox
12 / 16 / 5
Регистрация: 13.04.2011
Сообщений: 148
#1

Последовательная асинхронная загрузка файлов

14.08.2013, 06:23. Просмотров 2005. Ответов 6
Метки нет (Все метки)

Здравствуйте.

Пытаюсь сделать чтобы программа скачала 2 файла. Один из интернета, другой из локальной сети и показала скорость скачивания. Во время закачки чтобы все это отображалось в прогресс баре. Проблема в том что при асинхронной загрузке вызывающий поток не блокируется, а стало быть два последовательно запущенных метода выполняться в одно время. Вопрос, как сделать так чтобы после запуска первого метода DownloadFile, второй дождался завершения загрузки и только тогда запустился.

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
private void button1_Click(object sender, EventArgs e)
        {
            string globalUrl = "http://internet.yandex.ru/static/7.txt"; //ссылка на файл из интернета
            string localUrl = @"\\fs50.38ui.ru\music\Lossy\Slipknot\2008 - All Hope Is Gone\8. Slipknot - gehenna.mp3"; //ссылка на файл из локальной сети
            DownloadFile(globalUrl, 1);
            DownloadFile(localUrl, 2);
        }
 
        public void DownloadFile(string urlAddress, int i)
        {
            WebClient webClient = new WebClient();
            DateTime dt1 = new DateTime();
            DateTime dt2 = new DateTime();
            progressBar1.Value = 0;
            try
            {
                webClient.DownloadProgressChanged += (s, e) =>
                {
                    if (progressBar1.Value != e.ProgressPercentage)
                    {
                        progressBar1.Value = e.ProgressPercentage;
                        label1.Text = progressBar1.Value.ToString() + " %";
                    }
                };
 
                webClient.DownloadFileCompleted += (s, e) =>
                {
                    dt2 = DateTime.Now;
                    progressBar1.Value = 100;
                    FileInfo aFile = new FileInfo("data.dat");
                    double dltime = Math.Round((dt2 - dt1).TotalSeconds, 2);
                    string dSpeed = Math.Round(((aFile.Length / 1024 / 1024) / dltime) * 8, 2).ToString();
                    if (i == 1)
                    {
                        label3.Text = "Скорость интернет соединения: " + dSpeed + " Мбит/сек";
                    }
                    else
                    {
                        label4.Text = "Скорость локального соединения: " + dSpeed + " Мбит/сек";
                    }
                    aFile.Delete();
                };
                dt1 = DateTime.Now;
                webClient.DownloadFileAsync(new Uri(urlAddress), "data.dat");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.08.2013, 06:23
Ответы с готовыми решениями:

Асинхронная загрузка нескольких файлов по очереди
Есть List<string> _urls - в нем хранятся URL mp3 . textBox1.Text - там путь к...

DownloadFileAsync последовательная загрузка
Привет всем, у меня есть вот такой код: for (int i = 0; i...

Webclient, асинхронная загрузка
Добрый вечер. В своей программе в main я вызываю функцию LoadFile, которая...

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

Последовательная загрузка URL в webbrowser через 10 секунд из массива по таймеру
Что у меня неправильно? у меня в данный момент загружается всегда последний...

6
natrox
12 / 16 / 5
Регистрация: 13.04.2011
Сообщений: 148
16.08.2013, 08:39  [ТС] #2
В общем ничего не придумал умнее чем сделать через флаги и таймер. Плюс добавил еще графики в виде спидометров. Вот что получилось.
Последовательная асинхронная загрузка файлов


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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
string globalUrl = "http://internet.yandex.ru/static/7.txt"; //ссылка на файл из интернета
string localUrl = @"\\myshare\music\Lossy\Slipknot\2008 - All Hope Is Gone\8. Slipknot - gehenna.mp3"; //ссылка на файл из локальной сети
 
private void button1_Click(object sender, EventArgs e)
        {
            drawToZero(aquaGauge1,1);
            drawToZero(aquaGauge2, 5);
            label3.Text = "0 %";
            label3.Text = "";
            label4.Text = "";
            progressBar1.Value = 0;
            DownloadFile(globalUrl, 1);
            button1.Enabled = false;
            //DownloadFile(localUrl, 2);
        }
 
        public void DownloadFile(string urlAddress, int i)
        {
            WebClient webClient = new WebClient();
            DateTime dt1 = new DateTime();
            DateTime dt2 = new DateTime();
            progressBar1.Value = 0;
            try
            {
                webClient.DownloadProgressChanged += (s, e) =>
                {
                    if (progressBar1.Value != e.ProgressPercentage)
                    {
                        progressBar1.Value = e.ProgressPercentage;
                        label1.Text = progressBar1.Value.ToString() + " %";
                    }
                };
 
                webClient.DownloadFileCompleted += (s, e) =>
                {
                    dt2 = DateTime.Now;
                    progressBar1.Value = 100;
                    FileInfo aFile = new FileInfo("data.dat"); 
                    double dltime = Math.Round((dt2 - dt1).TotalSeconds, 2);
                    string dSpeed = Math.Round(((aFile.Length / 1024 / 1024) / dltime) * 8, 2).ToString();
                    if (i == 1)
                    {
                        label3.Text = "Скорость интернет соединения:   " + dSpeed + " Мбит/сек";
                        drawSpeed(aquaGauge1, Convert.ToDouble(dSpeed));
                        if (Convert.ToDouble(dSpeed) < 2)
                        {
                            linkLabel1.Visible = true;
                        }
                    }
                    else
                    {
                        label4.Text = "Скорость локального соединения: " + dSpeed + " Мбит/сек";
                        drawSpeed(aquaGauge2, Convert.ToDouble(dSpeed));
                        if (Convert.ToDouble(dSpeed) < 20)
                        {
                            linkLabel1.Visible = true;
                        }
                    }
                    aFile.Delete();
                    if (i==1) timer1.Enabled = true;
                    else button1.Enabled = true;
                };
                dt1 = DateTime.Now;
                webClient.DownloadFileAsync(new Uri(urlAddress), "data.dat");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            DownloadFile(localUrl, 2);
            timer1.Enabled = false;
        }
 
        private void drawSpeed(AquaGauge ag, double value)
        {
            BackgroundWorker bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.DoWork += delegate
            {
                for (int i = 0; i <= value; i++)
                {
                    bw.ReportProgress(i);
                    Thread.Sleep(50);
                }
            };
            bw.RunWorkerCompleted += delegate
            {
                //прорисовка закончилась
            };
            bw.ProgressChanged += (s, em) =>
            {
                ag.Value = em.ProgressPercentage;
            };
            bw.RunWorkerAsync();
        }
 
        private void drawToZero(AquaGauge ag, int x)
        {
            Random rd = new Random();
            int startIndex = Convert.ToInt32(ag.Value);
 
            BackgroundWorker bw = new BackgroundWorker();
            bw.WorkerReportsProgress = true;
            bw.DoWork += delegate
            {
                if (startIndex > 0)
                    for (int i = startIndex; i >= 0; i=i-x)
                    {
                        bw.ReportProgress(i);
                        Thread.Sleep(50);
                    }
                if (ag.Value != 0) ag.Value = 0;
            };
            bw.RunWorkerCompleted += delegate
            {
                //прорисовка закончилась
            };
            bw.ProgressChanged += (s, em) =>
            {
                ag.Value = em.ProgressPercentage;
            };
            bw.RunWorkerAsync();
        }
Было бы конечно круто сделать чтобы эти спидометры во время загрузки не просто стояли, а стрелки бегали как будто скорость вычисляется. Но мои попытки ничего хорошего не дали, к сожалению.
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,458
Записей в блоге: 5
Завершенные тесты: 4
16.08.2013, 10:00 #3
natrox, 1) нужно использоватть не DateTime, а Stopwatch, это раз.
2)
C#
1
2
3
4
5
6
7
8
9
10
 public WebClient DownloadFile(string urlAddress, int i)
{...}
 
private void button1_Click(object sender, EventArgs e)
        {
            string globalUrl = "http://internet.yandex.ru/static/7.txt"; //ссылка на файл из интернета
            string localUrl = @"\\fs50.38ui.ru\music\Lossy\Slipknot\2008 - All Hope Is Gone\8. Slipknot - gehenna.mp3"; //ссылка на файл из локальной сети
            var client = DownloadFile(globalUrl, 1);
            client.DownloadFileCompleted += (s, e) => DownloadFile(localUrl, 2);
        }
Добавлено через 24 минуты
Имхо в идеале должно это все выглядеть примерно так:
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
        private void Form1_Load(object sender, EventArgs e)
        {
            string globalUrl = "http://internet.yandex.ru/static/7.txt"; //ссылка на файл из интернета
            string localUrl = @"\\fs50.38ui.ru\music\Lossy\Slipknot\2008 - All Hope Is Gone\8. Slipknot - gehenna.mp3"; //ссылка на файл из локальной сети
            var internet = new Action(() => DownloadFile(globalUrl, (x, size) => label3.Text = "Скорость интернет соединения: " + size / x.Seconds + " Мбит/сек", ReportProgress));
            var local = new Action<Task>(t => DownloadFile(localUrl, (x, size) => label4.Text = "Скорость локального соединения: " + size/x.Seconds + " Мбит/сек", ReportProgress));
 
            var task = new Task(internet);
            task.ContinueWith(local);
            task.Start();
        }
        static readonly string FileName = Path.GetTempFileName();
 
        private void DownloadFile(string urlAddress, Action<TimeSpan, long> callbackResult,
                                  DownloadProgressChangedEventHandler reportProgress)
        {
            var client = new WebClient();
            var sw = new Stopwatch();
            client.DownloadProgressChanged += reportProgress;
            client.DownloadDataCompleted += (sender, e) =>
                                            {
                                                var fi = new FileInfo(FileName);
                                                sw.Stop();
                                                callbackResult(sw.Elapsed, fi.Length);
                                                fi.Delete();
                                            };
            sw.Start();
            try
            {
                client.DownloadFile(new Uri(urlAddress), FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 
        private void ReportProgress(object sender, DownloadProgressChangedEventArgs e)
        {
            if (progressBar1.Value != e.ProgressPercentage)
            {
                progressBar1.Value = e.ProgressPercentage;
                label1.Text = progressBar1.Value + " %";
            }
        }
1
natrox
12 / 16 / 5
Регистрация: 13.04.2011
Сообщений: 148
16.08.2013, 10:33  [ТС] #4
Цитата Сообщение от Psilon Посмотреть сообщение
нужно использовать не DateTime, а Stopwatch, это раз
Разве это принципиально важно? Или просто так будет правильнее?

Цитата Сообщение от Psilon Посмотреть сообщение
Имхо в идеале должно это все выглядеть примерно так
Ну да, согласен, у вас выглядит лучше и правильнее
0
Psilon
Master of Orion
Эксперт .NET
5989 / 4842 / 901
Регистрация: 10.07.2011
Сообщений: 14,458
Записей в блоге: 5
Завершенные тесты: 4
16.08.2013, 10:53 #5
natrox, stopwatch как минимум точнее Но там еще фишки есть, я уже не помню.
1
natrox
12 / 16 / 5
Регистрация: 13.04.2011
Сообщений: 148
16.08.2013, 12:20  [ТС] #6
Цитата Сообщение от Psilon Посмотреть сообщение
stopwatch как минимум точнее Но там еще фишки есть, я уже не помню.
Да я понимаю смысл в этом компоненте, но тут это не так критично. А вообще вы правы. Каждый компонент должен использоваться для той цели, для которой он предназначен.

Добавлено через 6 секунд
Цитата Сообщение от Psilon Посмотреть сообщение
stopwatch как минимум точнее Но там еще фишки есть, я уже не помню.
Да я понимаю смысл в этом компоненте, но тут это не так критично. А вообще вы правы. Каждый компонент должен использоваться для той цели, для которой он предназначен.
1
natrox
12 / 16 / 5
Регистрация: 13.04.2011
Сообщений: 148
21.08.2013, 08:11  [ТС] #7
Решил последовать мудрому совету и сделать все по нормальному, но код по какой-то причине не работает. Ошибок нет, но и выполнение не происходит. Просто запускается форма, а действий никаких нет. Из-за чего это может быть?

И еще вопрос, на .NET 2.0 это организовать не получиться, есть варианты как сделать что-то подобное?

Цитата Сообщение от Psilon Посмотреть сообщение
natrox,
Имхо в идеале должно это все выглядеть примерно так:
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
        private void Form1_Load(object sender, EventArgs e)
        {
            string globalUrl = "http://internet.yandex.ru/static/7.txt"; //ссылка на файл из интернета
            string localUrl = @"\\fs50.38ui.ru\music\Lossy\Slipknot\2008 - All Hope Is Gone\8. Slipknot - gehenna.mp3"; //ссылка на файл из локальной сети
            var internet = new Action(() => DownloadFile(globalUrl, (x, size) => label3.Text = "Скорость интернет соединения: " + size / x.Seconds + " Мбит/сек", ReportProgress));
            var local = new Action<Task>(t => DownloadFile(localUrl, (x, size) => label4.Text = "Скорость локального соединения: " + size/x.Seconds + " Мбит/сек", ReportProgress));
 
            var task = new Task(internet);
            task.ContinueWith(local);
            task.Start();
        }
        static readonly string FileName = Path.GetTempFileName();
 
        private void DownloadFile(string urlAddress, Action<TimeSpan, long> callbackResult,
                                  DownloadProgressChangedEventHandler reportProgress)
        {
            var client = new WebClient();
            var sw = new Stopwatch();
            client.DownloadProgressChanged += reportProgress;
            client.DownloadDataCompleted += (sender, e) =>
                                            {
                                                var fi = new FileInfo(FileName);
                                                sw.Stop();
                                                callbackResult(sw.Elapsed, fi.Length);
                                                fi.Delete();
                                            };
            sw.Start();
            try
            {
                client.DownloadFile(new Uri(urlAddress), FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 
        private void ReportProgress(object sender, DownloadProgressChangedEventArgs e)
        {
            if (progressBar1.Value != e.ProgressPercentage)
            {
                progressBar1.Value = e.ProgressPercentage;
                label1.Text = progressBar1.Value + " %";
            }
        }
0
21.08.2013, 08:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.08.2013, 08:11

Загрузка файлов на сервер
Пусть у нас есть файл и нам его надо загрузить на какой-то сервер, откуда я...

Загрузка файлов по http
Всех с наступающим! Беда у меня случилась. Раньше использовал для загрузки...

Загрузка файлов с uCoz
Здравствуйте, форумчане! Имеется сайт на данном хостинге. Нужно написать...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru