Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];

Вниз

Exeption внутри Thread   Найти похожие ветки 

 
Strate ©   (2007-05-12 15:55) [0]

Здравствуйте. Такой вопрос: если внутри потока возникает Exception, то этот поток тупо останавливается и всё. А хотелось бы уыидеть мессадж с ошибкой. Как можно сделать кроме try...except...finally (т.к. кода уже очень много, а я даже не представляю куда воткнуть его).


 
DVM ©   (2007-05-12 16:00) [1]


> Как можно сделать кроме try...except

никак.


> т.к. кода уже очень много, а я даже не представляю куда
> воткнуть его

Воткнуть туда, где возникает исключение. А еще лучше не допускать возникновения исключений.


 
Strate ©   (2007-05-12 16:06) [2]

DVM ©   (12.05.07 16:00) [1]
никак.


Жаль :(

DVM ©   (12.05.07 16:00) [1]
Воткнуть туда, где возникает исключение.

Так я хочу определить где оно возникает :)

P.S. Просто оно возникает далеко не всегда и не у меня на компе, что доставляет определённые сложности.


 
Dmitrij_K   (2007-05-12 16:16) [3]

If the Execute method raises an exception that is not caught and handled within that method, the thread terminates and sets FatalException to the exception object for that exception. Applications can check FatalException from an OnTerminate event handler to determine whether the thread terminated due to an exception.

В OnTerminate
if Thread.FatalException<>nil
then было исключение


 
Strate ©   (2007-05-12 16:29) [4]

Dmitrij_K   (12.05.07 16:16) [3]

А текст исключения достать можно?


 
Loginov Dmitry ©   (2007-05-12 17:04) [5]

> Так я хочу определить где оно возникает :)
>
> P.S. Просто оно возникает далеко не всегда и не у меня на
> компе, что доставляет определённые сложности.


Заключи в блок try...except все участки кода, где есть вероятность возникновения исключения. А вероятность этого, поверь, есть везде (абсолютно везде). Оформи каждый блок кода следующим образом:

try
 {...........}
except
 on E: Exception do
   raise Excpetion.Create("Blabla1 -> " + E.Message);
end;

а в конце все это дело заключи в общий try...except, где запиши текст ошибки в текстовый файл.


 
DVM ©   (2007-05-12 17:10) [6]


> А вероятность этого, поверь, есть везде (абсолютно везде).
>  

Противоречие с Вашими же словами про вероятность исключения в конструкторе и деструкторе TBitmap.

http://delphimaster.net/view/2-1178476227/

Так абсолютно везде или все таки не везде :)


 
Strate ©   (2007-05-12 17:31) [7]

Хм, сделал примерно так:

if TThread(Thread).FatalException<>nil then
   with Exception(TThread(Thread).FatalException) do
     ShowMessage("Произошла ошибка в потоке монитора. Свяжитесь с разработчиком"+
                #10#13"Сообщите текст ошибки:"#10#13+Message);


посмотрим как себя проявит. Если не сработает, то сделаю как советует Дмитрий


 
Loginov Dmitry ©   (2007-05-12 18:43) [8]

> Противоречие с Вашими же словами про вероятность исключения
> в конструкторе и деструкторе TBitmap.


Это совершенно иная ситуация. Дело в том, что бывают наведенные ошибки. Допустим где-то произошла ошибка, но исключения она не вызвала, зато через некоторое время происходит ошибка при выполнении совершенно тривиального кода, например, I := I + 1;
А вот узнать источник возникновения подобных ошибок иногда крайне сложно. Мне известно, что подобная ошибка может произойти при выполнении TQuery.Open. Ошибка следующая: "Invalid floating pointer operation". Может возникнуть только в случае, если в качестве TQuery.DataBaseName указывается путь к базе, и при этом отсутствует компонент TDataBase, у которого настроены параметры Params и псевдоним базы данных DataBaseName. Ошибку отлавливал целый день. Определил, что она возникает где-то в дебрях модуля BDE.dcu. Никакие try..finally или try..except не помогают. Заключаешь TQuery.Open в try..except - получается еще чуднее - запрос нормально отрабатывается, но программа валится на строчке I := I + 1;, которая расположена совершенно в другом модуле. Подключение компонента TDataBase полностью исправило описанную ситуацию (ошибка больше не появляется). Может вру. Может ошибка и не в дебрях BDE.dcu. Может какая другая dll-ка портит память, используемую БД-компонентами - не важно. Главное, что на практике ошибка может случится во время выполнения любой, даже самой безобидной строки программы.
Но это вовсе не повод, чтобы захломлять текст программы лишними блоками try..finally.


 
DVM ©   (2007-05-12 18:54) [9]


> Заключи в блок try...except все участки кода, где есть вероятность
> возникновения исключения. А вероятность этого, поверь, есть
> везде (абсолютно везде).

Вероятность исключения Delphi есть ДАЛЕКО НЕ ВЕЗДЕ. Например, функции WinAPI не могут генерировать Delphi исключений и код построенный только на вызовах API вряд ли сгенерит исключение, которое потребуется заключать в try...except.

А если возникает исключительная ситуация в сторонних библиотеках, то тут никакой try...except не поможет.


 
Джо ©   (2007-05-12 20:18) [10]

>
> [9] DVM ©   (12.05.07 18:54)
> функции WinAPI не могут генерировать Delphi исключений

Ммм... Ну, хотя бы вот так:
procedure TForm1.FormCreate(Sender: TObject);
var
 Sz: Cardinal;
begin
 GetUserName(nil,Sz)
end;

Запусти на WinXP и удивись.


> А если возникает исключительная ситуация в сторонних библиотеках,
> то тут никакой try...except не поможет.

Исключения, сгенерированные в «сторонних библиотеках» точно так же прекрасно обрабатываются при помощь try..except как и всякие другие.


 
DVM ©   (2007-05-12 20:44) [11]


> Ммм... Ну, хотя бы вот так:

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

Хотя конечно, верные в одном случае параметры могут стать неверными в другом случае.

Да, наверное я не совсем прав насчет Api-функций. Наверное, стоило сказать, что большинство API функций не генерят исключений.

В таком случае, мои рассуждения на необходимость двойного try...finally при создании/уничтожении двух битмапов (см. пост по ссылке) верны.


 
Джо ©   (2007-05-12 20:48) [12]

> [11] DVM ©   (12.05.07 20:44)
> Мда.. Это уже неправильное использование функций. Если функции
> переданы верные параметры, исключения не будет.

Гм. Вообще-то, исключительные ситуации именно и случаются, например, тогда, когда функции используются «неправильно». Если они используются «правильно», то никаких исключительных ситуаций, естественно, и не происходит.


 
Anatoly Podgoretsky ©   (2007-05-12 21:38) [13]

> DVM  (12.05.2007 18:54:09)  [9]

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


 
Loginov Dmitry ©   (2007-05-12 21:39) [14]

> В таком случае, мои рассуждения на необходимость двойного
> try...finally при создании/уничтожении двух битмапов (см.
> пост по ссылке) верны.


Вообще изпользование try..finally наиболее оправдано в тех случаях, когда от них зависит работоспособность программы. Например:

Table1.DisableControls;
try
 {...........}
finally
 Table1.EnableControls;
end;

FS := TFileStream.Create(...);
try
 {..............}
finally
 FS.Free;
end;

Canvas.Lock;
try
 {...........}
finally
 Canvas.Unlock;
end;

CS.Enter;
try
 {...........}
finally
 CS.Leave;
end;


В случаях же с TList, TStringList, TBitmap, TMemoryStream использование try..finally гораздо менее значимо, и в основном вставляем его по привычке. Взять например TList. Казалось бы, нафик так писать:


List := TList.Create;
try
 {...........}
finally
 List.Free;
end;


Че произойдет, если в {..........} произойдет исключение? Объект уничтожится. Исключение распространится до ближайшего обработчика. В конце концов пользователь, нажавший ту злополучную кнопочку, получит гневное сообщение об ошибке. Он еще раз нажмет - опять получит сообщение. Все, нажимать ему уже надоест (но на работу программы эта ошибка не повлияет). Делай try..finally или не делай - результат один. Но пользователь все-равно не узнает, что там использовался список TList, и он остался в памяти.
А вот, если забыть заключить в try..finally DisableControls/EnableControls, по пользователь в случае ошибки программы будет точно в шоке - нормального продолжения работы программы уже не будет. Пользователь выкенет такую программу тут же, и еще обработчиков обложит тем, чем надо.

Да.. К чему все это?..
В общем, хорошо, когда защита кода становится делом привычки. Главное не загоняться.


 
DVM ©   (2007-05-12 21:53) [15]


> Loginov Dmitry ©   (12.05.07 21:39) [14]

Я чего к этим битмапам привязался. Мне приходится иметь дело с кодом, где эти самые битмапы создаются/уничтожаются чуть ли не миллионами в сутки. И все это как раз в потоках. И все это должно работать чуть ли не месяцами без участия человека. Если где то битмап хоть раз в час не будет корректно уничтожен - лавинообразно система начинает терять ресурсы GDI и память. Тут не будет пользователя который нажмет кнопочку или заметит зависания приложения. Кирдык наступает очень быстро. Вот.


 
Loginov Dmitry ©   (2007-05-12 23:46) [16]

А причем тут потоки и миллионы битмапов? Причем тут ресурсы GDI?
При создании битмапов никакие ресурсы GDI не выделяются. Они будут использоваться, если задать битмапам ненулевые размеры, а размеры задаются не в конструкторе. Так что аргумент [15] здесь не подходит.


 
DVM ©   (2007-05-13 00:18) [17]


> При создании битмапов никакие ресурсы GDI не выделяются.
>  Они будут использоваться, если задать битмапам ненулевые
> размеры, а размеры задаются не в конструкторе.

Зачем нужен битмап нулевых размеров? Было бы глупо их создавать и не использовать. Ясное дело они ненулевых у меня - в них декодируются Jpeg - данные. Ресурсы GDI выделяются еще как. А конструктор тут вообще не при чем, сейчас речь о деструкторе и обязательной его отработке. Насчет исключения в конструкторе я тогда привел неудачный пример и поправил сам себя ниже. Так что все подходит.


> А причем тут потоки и миллионы битмапов?

Притом, что я на таких задачах привык писать код так, чтобы не ломать потом голову над тем куда и что у меня утекает. А потоки здесь при том, что у автора в вопросе потоки. Ресурсы GDI при том же, что и битмапы.


 
DVM ©   (2007-05-13 00:18) [18]


> При создании битмапов никакие ресурсы GDI не выделяются.
>  Они будут использоваться, если задать битмапам ненулевые
> размеры, а размеры задаются не в конструкторе.

Зачем нужен битмап нулевых размеров? Было бы глупо их создавать и не использовать. Ясное дело они ненулевых у меня - в них декодируются Jpeg - данные. Ресурсы GDI выделяются еще как. А конструктор тут вообще не при чем, сейчас речь о деструкторе и обязательной его отработке. Насчет исключения в конструкторе я тогда привел неудачный пример и поправил сам себя ниже. Так что все подходит.


> А причем тут потоки и миллионы битмапов?

Притом, что я на таких задачах привык писать код так, чтобы не ломать потом голову над тем куда и что у меня утекает. А потоки здесь при том, что у автора в вопросе потоки. Ресурсы GDI при том же, что и битмапы.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.049 c
1-1175700339
Mr. D.
2007-04-04 19:25
2007.06.03
TStringGrid, выделение по правой кнопки мыши


2-1178858232
ZEN_ToS
2007-05-11 08:37
2007.06.03
Автоматический запуск программы при загрузке Windows


15-1178736595
ANTPro
2007-05-09 22:49
2007.06.03
Подскажите где ошибка


1-1175524308
DelphiLexx
2007-04-02 18:31
2007.06.03
Аналог TNotebook, но поддерживающий наследование


2-1179226884
Provodnick
2007-05-15 15:01
2007.06.03
Строку с #0 в XML





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский