Обработка ошибок в OTL.
Одной из важных особенностей разработки многопоточных приложений является правильная обработка ошибок в фоновых потоках. Многие из Вас сталкивались с тем, что созданный Вами фоновый поток вдруг внезапно завершает работу. Обычно и наиболее часто это вызвано ошибкой произошедшей в коде фонового потока. Библиотека OTL предлагает хороший механизм отслеживание ошибок в фоновых потоках.
Рассмотрим этот механизм на демонстрационном примере tests\ 13_Exceptions. В приведенном ниже коде метода фоновой задачи:
test_13_Exceptions.pas Преднамеренное создание ошибок в фоновой задаче.
procedure TfrmTestExceptions.TestException(const task: IOmniTask);
var
i : array [1..1] of integer;
msg: TOmniMessage;
begin
WaitForSingleObject(task.Comm.NewMessageEvent, INFINITE);
task.Comm.Receive(msg);
if msg.MsgID = EXC_AV then
PChar(nil)^ := #0
else if msg.MsgID = EXC_RC then begin
i[1] := 42;
i[i[1]] := 0;
end
else
raise ECustomException.Create('Exception test');
end;
принудительно генерируются (по поступившему событию) различные виды ошибок: Access Violation, Range Check, Custom Exception. После этого фоновый поток прекращает свою работу. В методе RunTest запускается наш тестовый поток и далее контролируется, как поток был завершен.
test_13_Exceptions.pas
procedure TfrmTestExceptions.RunTest(Sender: TObject);
var
task: IOmniTaskControl;
begin
task := CreateTask(TestException);
. . .
// Посылка сообщений фоновой задачи, для имитации ошибки
if Sender = btnAV then
task.Comm.Send(EXC_AV)
else if Sender = btnRC then
task.Comm.Send(EXC_RC)
else
task.Comm.Send(EXC_CUSTOM);
. . .
task.WaitFor(30000); // Ожидаем завершение задачи
// Смотрим код завершения и ошибку.
Log(Format('%d %s', [task.ExitCode, task.ExitMessage]));
end;
В свойствах ExitCode и ExitMessage (IOmniTaskControl) возвратятся код ошибки и сообщение об ошибке. Как видите, ошибки перехватываются непосредственно OTL и в дальнейшем разработчик сможет их корректно обработать. Однако такая обработка ошибок возможна только после включения данного механизма OTL методом SilentExceptions. Если данный метод не будет вызван, то при возникновении ошибки будет вызван стандартный обработчик ошибок Delphi. Так-же в демонстрационном примере, показана обработка ошибок в объектах потомках TOmniWorker, реализующих фоновую задачу, а не только в методах. Обработка осуществляется точно так-же.
Комментариев нет:
Отправить комментарий