0

したがって、この質問は、.Net IAsyncResultデザインパターンと、この質問EndInvokeでカバーされている呼び出しの必要性に関するものです。

バックグラウンド

特定の関数への潜在的に多くの非同期呼び出しを開始し、これらすべての呼び出しが終了するのを待ってEndInvoke()から、すべての結果を取得するために使用するコードがあります。

質問1

呼び出すまで、いずれかの呼び出しで例外が発生したかどうかはわかりません。いずれかの呼び出しEndInvoke()で例外が発生した場合、メソッド全体が失敗し、例外がAPI固有の例外にラップされて、上位にスローされます。

だから私の最初の質問は、残りの非同期呼び出しが適切に終了することを保証するための最良の方法は何ですか?

終了していない残りの呼び出しを呼び出す(そしてそれ以上の例外を無視する)finallyブロックは、これを行うための最良の方法ですか?EndInvoke()

質問2

次に、最初にすべてのasyc呼び出しを開始するときに、インスタンスから取得したインスタンスWaitHandle.WaitAll()の配列を呼び出します。これらすべての非同期呼び出しを起動しているメソッドには、順守するタイムアウトがあるため、これをメソッドに提供します。次に、すべての呼び出しが完了したかどうかをテストします。完了していない場合は、タイムアウトに達している必要があります。これにより、メソッドも失敗し、別のAPI固有の例外がスローされます。WaitHandleIAsyncResultWaitAll()

だから私の2番目の質問はこの場合私は何をすべきかということです。

エラーをスローする前に、これらすべての非同期呼び出しを終了するために呼び出す必要がありEndInvoke()ますが、同時に、EndInvoke()がブロックされているため、コードがスタックしないようにします。理論的には、少なくともWaitAll()呼び出しがタイムアウトした場合、すべての非同期呼び出しはタイムアウトによって制御されているため、すべての非同期呼び出し自体がタイムアウトになり、例外がスローされます(したがって呼び出しが完了します)が、このタイムアウトはメインのタイムアウトとは異なる可能性があります

4

2 に答える 2

1

オブジェクトを繰り返し処理し、生成された例外を別の場所に格納するtry/catchでIAsyncResultそれぞれをラップします。EndInvoke次に、すべてのを呼び出しEndInvokeたら、例外が保存されているかどうかを確認し、保存されている場合はAPI例外をスローします。何かのようなもの:

var exs = new List<Exception>();

foreach (IAsyncResult iasr in asyncResults) {
    try {
        iasr.EndInvoke();
    }
    catch (Exception e) {
        exs.Add(e);
    }
}

if (exs.Count > 0) {
    throw new MyException(exs.ToReadOnly());
}
于 2010-06-14T11:48:45.740 に答える
0

可能であれば、IAsyncResultの代わりにタスクを使用することをお勧めします。これらはより優れた「継続」セマンティクスを備えており、IAsyncResult APIをラップして、EndInvokeを適切に呼び出すことができます。

于 2010-06-14T13:27:41.203 に答える