ThreadPool WorkItemが完了したことを検出/完了を待機
-
03-07-2019 - |
質問
何らかの理由で、 ThreadPool
の QueueWorkItem
は、 IAsyncResult
またはその他のワークアイテムへのハンドルを返さないため、完了するまで待つ RegisterWait ...
メソッドがありますが、 WaitHandle
を渡す必要があり、それらの作成は高価です( IAsyncResult
のドキュメントを参照してください。要求されるまで WaitHandle
の作成を遅らせます)。 Task Parallel Libraryはこの欠如を修正しますが、それが利用可能になるまでに長い待ち時間があります。そのため、この設計には問題がありますか
public class Concurrent<T> {
private ManualResetEvent _resetEvent;
private T _result;
public Concurrent(Func<T> f) {
ThreadPool.QueueUserWorkItem(_ => {
_result = f();
if (_resetEvent != null)
_resetEvent.Set();
});
}
public WaitHandle WaitHandle {
get {
if (_resetEvent == null)
_resetEvent = new ManualResetEvent(_result != null);
return _resetEvent;
}
...
編集: 懸念についてのフォローアップ質問をしましたThreadPoolの代わりに非同期デリゲートを使用する場合に発生します。
解決
まあ、WaitHandleを取得してから設定するまでの間に競合状態があります。呼び出し側が少し遅れた場合、発信者が永遠に待機することを本当に望みますか?
おそらく適切なロックをいくつか行い、「終了しました」を保持する必要があります。フラグを作成して、完了後にWaitHandleを行う場合は、返す前に設定します。
また、パブリックコンストラクターを使用するのではなく、個人的に静的ファクトリーメソッドを作成するか、「作成して then 明示的に開始」するようにします。パターン。コンストラクターで作業項目をキューイングするのは奇妙に感じます。
他のヒント
非同期デレゲートを使用していない理由は、次のとおりです。
http://msdn.microsoft.com/en-us/library /h80ttd5f.aspx
それにより、コンカレントが時代遅れになりますか?