Форум: "Начинающим";
Текущий архив: 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.52 MB
Время: 0.055 c