Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
1

Обработка исключений

15.01.2014, 16:55. Просмотров 1215. Ответов 19
Метки нет (Все метки)

Доброго времени суток,уважаемые форумчане.Помогите с обработкой исключений.
Сделал функцию скачивания файла в другом потоке.Если например ссылка на файл будет битая,то выкидывается исключение,но проблема: При вызове сообщения в котором находится текст исключения,то выдается очень много окон(10-20) вместо одного.В чем проблема?
Сообщение о исключении вызываю так:
C#
1
2
var ex = web.Message;
                MessageBox.Show(ex);
Вот сам код скачивания файла:
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
private void DownloadGameClient(object startPoint)
        {
            CheckForIllegalCrossThreadCalls = false; // Особо сильно не пинать,я перешел на темную сторону
            Enter_Game.Enabled = false;
            try
            {
                Form_Close.Enabled = false;
                var startPointInt = Convert.ToInt32(startPoint);
                if (Server_Change.Text == @"Hitech (PvP)" || Server_Change.Text == @"Hitech (PvE)")
                    webRequest = (HttpWebRequest) WebRequest.Create(urlForDownloadHitech);
                if (Server_Change.Text == @"SandBox (PvP)" || Server_Change.Text == @"SandBox (PvE)")
                    webRequest = (HttpWebRequest) WebRequest.Create(urlForDownloadSandbox);
                if (Server_Change.Text == @"RPG (PvP)")
                    webRequest = (HttpWebRequest)
                        WebRequest.Create(urlForDownloadRPG);
 
                webRequest.AddRange(startPointInt);
 
                webRequest.Credentials = CredentialCache.DefaultCredentials;
                webResponse = (HttpWebResponse) webRequest.GetResponse();
                var fileSize = webResponse.ContentLength;
 
                strResponse = webResponse.GetResponseStream();
                if (startPointInt == 0)
                {
                    strLocal = new FileStream(SavePath, FileMode.Create, FileAccess.Write, FileShare.None);
                }
                else
                {
                    strLocal = new FileStream(SavePath, FileMode.Append, FileAccess.Write, FileShare.None);
                }
 
                int bytesSize;
                var downBuffer = new byte[2048];
 
                while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
                {
                    strLocal.Write(downBuffer, 0, bytesSize);
                    Invoke(new UpdateProgessCallback(UpdateProgress),
                        new object[] {strLocal.Length, fileSize + startPointInt});
 
                }
            }
            catch (WebException web)
            {
                var ex = web.Message;
                MessageBox.Show(ex);
            }
            finally
            {
                if (prgDownload.Value == prgDownload.Maximum)
                {
                    var unpack = new ZipFile(SavePath);
                    unpack = ZipFile.Read(SavePath);
                    unpack.ExtractAll(GetVersion());
                    unpack.Dispose();
                    prgDownload.Value = 0;
                    Form_Close.Enabled = true;
                    Enter_Game.Enabled = true;
                    strResponse.Close();
                    strLocal.Close();
                    if (MD5jar())
                    {
                        lblProgress.Text = @"Loading was successful.";
 
                        if (IsJavaRunning())
                        {
                            Launch(chtext);
                        }
                    }
                    else
                    {
                        lblProgress.Text = @"The download was not successful.Try again";
                    }
                }
            }
        }
lblProgress = метка с отображением процесса загрузки и веса файла
prgDownload = progressbar для отображения процесса загрузки

Заранее спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.01.2014, 16:55
Ответы с готовыми решениями:

Обработка исключений
В моей программе при обработке исключения вызывается метод out_of_range ...

Обработка исключений, оператор if
Вот такой вот кусочек кода. В данном случае функция возвращает строку, которая формируется из...

Обработка исключений на С# вызванных в библиотеке С++
Вопрос: Как обработать исключение в проекте на платформе .NET, с подключенной библиотекой...

Обработка исключений сервера при WebClient.DownloadFile
Серверное приложение на ASP.NET отдаёт файл по определенному запросу. Клиентское приложение с...

19
0 / 0 / 0
Регистрация: 25.12.2013
Сообщений: 42
15.01.2014, 17:29 2
По коду ничего подозрительного не заметил, но если MessageBox выплывает много раз, логично предположить что его много раз вызвали. Вопрос кто и почему?

В самом private void DownloadGameClient(object startPoint) try-cache не в цикле. Может что-то выше вызывает DownloadGameClient(object startPoint) много раз если он не выполнился как следует?
Плюс конечно поставить брейкпоинт на MessageBox.Show() и оттуда шаг за шагом отследить кто же вызывает его повторно.

То что я тут написал конечно не рецепт, но может что-то натолкнет тебя на нужную идею.
Удачи
0
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
15.01.2014, 17:41  [ТС] 3
Спасибо,сейчас буду пробовать.

Вот на этой строчке выбивает IOException
C#
1
strLocal = new FileStream(SavePath, FileMode.Create, FileAccess.Write, FileShare.None);
И самое интересное что WebException вообще никогда не вызывается(breakpoint)
При неправильной ссылке происходит InvalidOperationException вот тут:
C#
1
webResponse = (HttpWebResponse) webRequest.GetResponse();
Добавлено через 3 минуты
Вот как вызывается метод загрузки:
C#
1
2
3
4
5
lblProgress.Visible = true;
                        prgDownload.Visible = true;
                        lblProgress.Text = @"Download Starting...";
                        thrDownload = new Thread(DownloadGameClient);
                        thrDownload.Start(0);
0
0 / 0 / 0
Регистрация: 25.12.2013
Сообщений: 42
15.01.2014, 17:46 4
Цитата Сообщение от Nitrogen_52rus Посмотреть сообщение
Вот на этой строчке выбивает IOException
C#
1
strLocal = new FileStream(SavePath, FileMode.Create, FileAccess.Write, FileShare.None);
Получается что strLocal.Close(); выполняется только если prgDownload.Value == prgDownload.Maximum
А оно наверно не всегда так. Попробуй его закрывать в любом случае, даже если не все докачалось до конца. Когда он будет закрыт, сможешь его переписать заново/дописать.
0
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
15.01.2014, 17:59  [ТС] 5
Пробовал сделать так:
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
finally
            {
                strResponse.Close();
                strLocal.Close();
                if (prgDownload.Value == prgDownload.Maximum)
                {
                    var unpack = new ZipFile(SavePath);
                    unpack = ZipFile.Read(SavePath);
                    unpack.ExtractAll(GetVersion());
                    unpack.Dispose();
                    prgDownload.Value = 0;
                    Form_Close.Enabled = true;
                    Enter_Game.Enabled = true;
                    if (MD5jar())
                    {
                        lblProgress.Text = @"Loading was successful.";
 
                        if (IsJavaRunning())
                        {
                            Launch(chtext);
                        }
                    }
                    else
                    {
                        lblProgress.Text = @"The download was not successful.Try again";
                    }
                }
            }
Но все равно выкидывает много окон об исключении.Причем больше выкидывает InvalidOperationException
Пробовал завершать поток таким способом:
C#
1
thrDownload.Abort();
Но разницы нет.
Вот еще пару строк кода которые относятся к этому методу:
C#
1
2
3
4
5
6
7
private Thread thrDownload;
        private Stream strResponse;
        private Stream strLocal;
        private HttpWebRequest webRequest;
        private HttpWebResponse webResponse;
        private static int PercentProgress;
        private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes);
0
0 / 0 / 0
Регистрация: 25.12.2013
Сообщений: 42
15.01.2014, 18:18 6
Когда у меня бывали примерно такие-же ситуации, помогало вырубить (на время) try-catch
То-есть просто выполнение кода без перехвата исключений.
Само собой при исключении тебя выкинет в дебаг. Там уже понятней будет.
В принципе, по возможности стараюсь обходиться без try-catch. Во всяком случае на стадии разработки.
Так легче вылечить все эти исключения. В конце, когда программу надо выдавать клиенту, там уже и try-catch вставляю с MessageBox
Плюс, стараюсь ставить try-catche на маленькие блоки изолируя тот самый catch
Иначе можно всю программу в try-catche загнать.. Потом только ищи из за чего он сработал..
0
331 / 267 / 18
Регистрация: 19.01.2011
Сообщений: 597
16.01.2014, 11:16 7
Изучите внимательно стек вызовов Ваших ошибок. Судя по всему - они разные. Замените catch (WebException web) на catch (Exception ex) или добавьте блок на остальные ошибки. IOException при создании файла - вполне возможно конфликты из-за нескольких потоков (ошибка при создании файла). и немного не понятны строки
C#
1
2
var unpack = new ZipFile(SavePath);
unpack = ZipFile.Read(SavePath);
- дважды делается одно и тоже.
IMHO, CheckForIllegalCrossThreadCall s в true лучше оставлять, как минимум в Debug.
Ну и я все таки вынес бы из блока finally логику работы с "удачными" данными при нормальном завершении блока try. finally будет выполнен всегда, если исключение было перехвачено приложением, в обратном случае, выполнение этого кода зависит от настроек ОС.

Цитата Сообщение от Nitrogen_52rus Посмотреть сообщение
И самое интересное что WebException вообще никогда не вызывается(breakpoint)
- само собой, потому что оно не возникает...
0
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
17.01.2014, 15:16  [ТС] 8
Вот такие ошибки происходят если поставить блок catch на облаву всех исключений(Exception)
0
Миниатюры
Обработка исключений  
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
17.01.2014, 15:47 9
Цитата Сообщение от Nitrogen_52rus Посмотреть сообщение
Вот такие ошибки происходят если поставить блок catch на облаву всех исключений(Exception)
У вас поток или несколько потоков вызывают один и тот же метод несколько раз, что не поддерживается объектом, дождитесь окончания выполнения метода и только потом вызывайте его еще раз или с каждым вызовом создавайте новый объект WebRequest.
0
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
17.01.2014, 16:06  [ТС] 10
Цитата Сообщение от Grishaco Посмотреть сообщение
У вас поток или несколько потоков вызывают один и тот же метод несколько раз, что не поддерживается объектом, дождитесь окончания выполнения метода и только потом вызывайте его еще раз или с каждым вызовом создавайте новый объект WebRequest.
Спасибо.В этом куске кода поставил catch и на него повесил перезапуск загрузки...Из-за этого и были проблемы.
C#
1
2
3
4
5
6
7
public void UpdateProgress(Int64 BytesRead, Int64 TotalBytes)
        {
                PercentProgress = Convert.ToInt32((BytesRead*100)/TotalBytes);
                prgDownload.Value = PercentProgress;
                lblProgress.Text = @"Downloaded " + BytesRead + @" out of " + TotalBytes + @" (" + PercentProgress + @"%)";
            
        }
Но теперь при битой ссылке возникает ArgumentOutOfRangeException.Ка к лучше обработать?
0
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
17.01.2014, 16:13 11
Цитата Сообщение от Nitrogen_52rus Посмотреть сообщение
Но теперь при битой ссылке возникает ArgumentOutOfRangeException.Ка к лучше обработать?
Вы когда пишете приводите сообщение ошибки и еще в дополнение StackTrace не помешает.
1
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
17.01.2014, 16:22  [ТС] 12
Цитата Сообщение от Grishaco Посмотреть сообщение
Вы когда пишете приводите сообщение ошибки и еще в дополнение StackTrace не помешает.
Выбивает на этой строчке:
C#
1
 prgDownload.Value = PercentProgress;
0
Миниатюры
Обработка исключений  
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
17.01.2014, 16:25 13
В прогресс баре у вас наверное значения от 0 до 100? А вы пытаетесь присвоить значение меньше нуля, вот он и кидает исключение.

Разберитесь вот с этой строчкой, некорректно вычисляется позиция прогресс бара.

C#
1
PercentProgress = Convert.ToInt32((BytesRead*100)/TotalBytes);
0
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
17.01.2014, 16:31  [ТС] 14
Grishaco, А как лучше вычислять?(Код вычисления позиции брал с другого форума)
0
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
17.01.2014, 16:34 15
Цитата Сообщение от Nitrogen_52rus Посмотреть сообщение
А как лучше вычислять?(Код вычисления позиции брал с другого форума)
Ну вот на вскидку

C#
1
2
3
4
double bytesIn = double.Parse(BytesReceived.ToString()); //Получено
        double totalBytes = double.Parse(TotalBytesToReceive.ToString());//Всего
        double percentage = bytesIn / totalBytes * 100;
        progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());
1
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
17.01.2014, 16:49  [ТС] 16
Grishaco, Тоже самое.
0
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
17.01.2014, 16:55 17
Какое значение приходит в этой переменной BytesRead? Видимо проблема в корректном получении количества полученных байтов. Разбирайтесь с ней.
1
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
17.01.2014, 17:08  [ТС] 18
Цитата Сообщение от Grishaco Посмотреть сообщение
Какое значение приходит в этой переменной BytesRead? Видимо проблема в корректном получении количества полученных байтов. Разбирайтесь с ней.
Это исключение выкидывается если ссылка битая(не рабочая)
0
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
17.01.2014, 17:12 19
Лучший ответ Сообщение было отмечено tezaurismosis как решение

Решение

Цитата Сообщение от Nitrogen_52rus Посмотреть сообщение
Это исключение выкидывается если ссылка битая(не рабочая)
тогда так

C#
1
2
3
4
5
6
if(BytesRead>=0)
{
PercentProgress = Convert.ToInt32((BytesRead*100)/TotalBytes);
                prgDownload.Value = PercentProgress;
                lblProgress.Text = @"Downloaded " + BytesRead + @" out of " + TotalBytes + @" (" + PercentProgress + @"%)";
}
1
5 / 5 / 3
Регистрация: 31.07.2013
Сообщений: 98
17.01.2014, 18:34  [ТС] 20
Grishaco, Огромное спасибо.Все получилось.
Еще вопрос: как сделать в этой строчке:
C#
1
lblProgress.Text = @"Downloaded " + BytesRead + @" out of " + TotalBytes + @" (" + PercentProgress + @"%)";
скорость загрузки файла?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.01.2014, 18:34

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

Перехват исключений
Здравствуйте, пытаюсь перехватывать исключения в оконном приложении таким кодом: using System;...

Правильный проброс исключений
Как по уму делают проброс исключений чтобы не было потерь в стеке?

Обработка исключений. Как организовать общий обработчик исключений?
У меня есть последовательность вызова методов для внесения данных в таблицу БД. Сам метод...

Обработка исключений
Есть клиент-серверная программа учёта товаров на складе. Всю информацию из БД вычитываю в datagrid....


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

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

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