4

なんらかの理由で、は作業項目に やその他ThreadPoolのハンドルをQueueWorkItem返さないためIAsyncResult、作業が完了するまで待機することができます。メソッドはありRegisterWait...ますが、a を渡す必要がWaitHandleあり、それらの作成にはコストがかかります (ドキュメントを参照してください。要求さIAsyncResultれるまで a の作成を遅らせることをお勧めします)。WaitHandleTask 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 の代わりに非同期デリゲートを使用するときに発生する懸念について、フォローアップの質問をしました

4

2 に答える 2

6

さて、WaitHandleをフェッチしてから設定するまでの間に競合状態が発生します。発信者が少し遅れた場合に、発信者が永遠に待機することを本当に望んでいますか?

おそらく、適切なロックを行い、「終了しました」フラグを保持して、終了後にWaitHandleを作成した場合は、それを返す前に設定する必要があります

また、パブリックコンストラクターを使用するだけでなく、静的ファクトリメソッドを個人的に作成するか、「作成してから明示的に開始する」パターンにします。コンストラクターで作業項目をキューに入れるのは、私には奇妙に感じます。

于 2009-01-02T00:25:12.867 に答える
3

ここでデモストレートされているように、非同期デリゲートを使用しないのはなぜですか。

http://msdn.microsoft.com/en-us/library/h80ttd5f.aspx

それは Concurrent を時代遅れにするでしょう?

于 2009-01-02T01:32:59.313 に答える