2016-03-28 4 views
0

Я использую IOmniTaskControl/TOmniWorker для выполнения кода последовательности в конкретный поток. Я буду повторно использовать этот IOmniTaskControl для нескольких вызовов Invoke. Как проверить исключения, которые могли произойти во время Invoke? Это вопрос на вопрос/ответ: Waiting for Invoke to finish when using IOmniTaskControl/TOmniWorker.Как я могу проверить исключения при использовании IOmniTaskControl/TOmniWorker?

Я проверил ExitCode и FatalException IOmniTaskControl, но они не установлены. Кажется, что IOmniTaskControl автоматически создаст новую задачу для каждого вызова Invoke, и исключение будет помещено в эту задачу, если это произойдет. Тем не менее, я не имею ссылки на эту задачу после завершения Invoke. Я использую TOmniWaitableValue для отметки, когда invoke завершает работу, но не ясно, что мне нужно сделать, чтобы сделать любое исключение, которое имело место для меня по возвращении из WaitFor (...).

Вот фрагмент структуры у меня есть:

interface 

type 
    TMyTaskProc = reference to procedure; 

    TMyTask = class 
    private 
    FWorker:  IOmniWorker; 
    FTaskControl: IOmniTaskControl; 
    FWaitable: IOmniWaitableValue; 
    public 
    constructor Create; 
    destructor Destroy; override; 

    procedure AwaitInvoke(Proc: TMyTaskProc); overload; 
    end; 

implementation 

type 
    TMyTaskWorker = class(TOmniWorker); 

constructor TMyTask.Create; 
begin 
    inherited; 

    FWorker := TMyTaskWorker.Create; 
    FTaskControl := CreateTask(FWorker).Run; 
    FWaitable := TOmniWaitableValue.Create; 
end; 

destructor TMyTask.Destroy; 
begin 
    FTaskControl.Terminate; 
    FTaskControl := nil; 

    FWaitable := nil; 

    inherited; 
end; 

procedure TMyTask.AwaitInvoke(Proc: TMyTaskProc); 
begin 
    FWaitable.Reset; 

    FTaskControl.Invoke(
    procedure 
    begin 
     try 
     Proc(); 
     finally 
     FWaitable.Signal; 
     end; 
    end 
); 

    FWaitable.WaitFor(INFINITE); 
end; 

Таким образом, в приведенном выше настройки, как я могу проверить после FWaitable.WaitFor (INFINITE) для каких-либо исключений, которые могли произойти во время Proc() вызов. Я хотел бы просто поднять его снова в тот момент в вызывающем потоке.

+0

Не могли бы вы создать полную программу, которая вызвала бы исключение? Таким образом, нам не нужно было догадываться. Похоже, мы должны спросить об этом почти по всем вопросам. –

+0

Не уверен, было ли это ясно или нет, но я не говорил о конкретном исключении. Я просто пытаюсь настроить код для обработки возможных исключений в вызове Proc(). Не показалось необходимым предоставить полную рабочую программу, включающую фиктивное исключение в вызове Proc(). Фактически, Габр дал мне ответ, который мне нужен. –

+0

Хорошо продолжайте писать наполовину вопрос тогда. Если у вас есть то, что вам нужно, что еще важно? –

ответ

1

Вы должны поймать исключение в тот момент, когда вы вызываете Proc, а затем каким-то образом уведомляете вызывающего абонента об этой ситуации. Например:

FTaskControl.Invoke(
    procedure 
    var 
    return: TOmniValue; 
    begin 
    return := TOmniValue.Null; 
    try 
     try 
     Proc(); 
     except 
     return.AsException := AcquireExceptionObject; 
     end; 
    finally 
     FWaitable.Signal(return); 
    end; 
    end 
); 

FWaitable.WaitFor(INFINITE); 
if FWaitable.Value.IsException then begin 
    Writeln('Caught exception ' + FWaitable.Value.AsException.ClassName); 
    FWaitable.Value.AsException.Free; 
end; 
+2

Это нехорошо. Объект исключения уничтожается, когда обработчик исключений завершается. Вам нужно 'AcquireExceptObject'. –

+1

@ ДавидХеффернан, конечно. Я забыл, как работает мое собственное программное обеспечение :((Похоже, что TOmniValue.AsException справляется с этим.) Исправлено. – gabr

+0

Спасибо, что я сам поймал исключение, и это был подход, который я собирался принять, если не было чего-то, чего я не видел чтобы уже предоставить возможности, которые мне нужны. И я бы использовал AqcuireExceptObject. –

 Смежные вопросы

  • Нет связанных вопросов^_^