вторник, 28 сентября 2010 г.

Использование OmniThread Libray (OTL) для создания многопоточных приложений - 7

Обработка ошибок в 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, реализующих фоновую задачу, а не только в методах. Обработка осуществляется точно так-же.

Комментариев нет:

Отправить комментарий