1

次のTPLタスクがあります

public abstract class AggregatorBase : IAggregator
{

    public void Start(CancellationToken token)
    {
        var parent = Task.Factory.StartNew(x =>
        {
            Aggregate(token);
        },TaskCreationOptions.LongRunning, token);

        parent.Wait();
    }

    public abstract void Aggregate(CancellationToken ct);
}

Aggregateメソッドの実装内に、Observable.Subscriptionの末尾が次のようなものがいくつかあります。

   public override void Aggregate(CancellationToken ct)
   {
            this.observables.Subscribe(// Do stuff);
            this.observables.Subscribe(// Do more stuff);

            while (!token.IsCancellationRequested)
            {
                System.Threading.Thread.Sleep(1000)
            }
   }

質問は、タスクを存続させ、すべてのサブスクリプションをスピンせずにアクティブに保つための最良の方法は何ですか?

4

1 に答える 1

1

キャンセル トークンの待機ハンドルを待機します。

while ( !token.IsCancellationRequested )
{
    if ( token.WaitHandle.WaitOne( timeout ) )
    {
        // cancelled. Don't have to do anything here, the above while 
        // loop will break now.
    }
    else
    {
        // ''timeout' period elapsed - do some periodic work here.
    }

}

編集: このスレッドで行う定期的な作業がない場合はWaitOne、タイムアウト パラメータなしでオーバーロードを使用するだけです。

token.WaitHandle.WaitOne();

キャンセルトークンが通知されるまで無期限に待機し、続行します。

EDIT2:

オブザーバブルのサブスクリプション内に while ループがあるとあなたが言ったことを読みました。すべてのオブザーバブル サブスクリプションをセットアップした直後にする必要がありますが、実際の各サブスクリプション コールバック内ではありません (これらのサブスクリプションは、サブスクリプションをセットアップしたタスク スレッドではなく、ソース イベントを呼び出したスレッドまたは他のスレッド プール スレッドで実行される可能性があります)。 )。

于 2012-02-23T01:04:40.407 に答える