2016-03-28 10 views
0

IOmniTaskControl/TOmniWorkerを使用して、特定のスレッドにコードを実行させています。このIOmniTaskControlを複数のInvoke呼び出しに対して繰り返し再利用します。 Invoke中に発生した可能性がある例外をチェックするにはどうすればよいですか?これは質問/回答への質問の続きです:Waiting for Invoke to finish when using IOmniTaskControl/TOmniWorkerIOmniTaskControl/TOmniWorkerの使用時に例外を確認するにはどうすればよいですか?

IOmniTaskControlのExitCodeとFatalExceptionをチェックしましたが、設定されていません。 IOmniTaskControlは、各Invoke呼び出しに対して自動的に新しいタスクを作成し、例外が発生した場合にそのタスクに配置されるように見えます。しかし、Invokeの完了後にそのタスクへの参照はありません。私はTOmniWaitableValueを使用して、呼び出しが完了したときにフラグを立てますが、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; 

したがって、上記の設定では、どのように私はPROC(中に発生した可能性のある例外のFWaitable.WaitFor(INFINITE)の後に確認することができます)コール。私はちょうど呼び出しスレッドのその時点で再度それを発生させたいと思います。

+0

例外が発生した完全なプログラムを作成できませんでしたか?そうすれば、私たちは推測する必要はありません。ここではほとんどすべての質問でこれを尋ねなければならないような気がします。 –

+0

明確かどうかは分かりませんが、特定の例外については言及していませんでした。私はProc()呼び出しで起こりうる例外を処理するコードをセットアップしようとしています。 Proc()呼び出しで偽の例外を含む完全な作業プログラムを提供する必要はないようです。実際、Gabrは私に必要な答えを私に与えてくれました。 –

+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'が必要です。もちろん@DavidHeffernan、 –

+1

。私は自分のソフトウェアがどう働いているのか忘れていました。(TOmniValue.AsExceptionがそれを処理していた印象でした)固定。 – gabr

+0

自分自身で例外を捕まえてくれてありがとうございました。 –

関連する問題