2

ContinueWhenAll を適切に使用していることを確認したいと思います。非同期で実行される呼び出しが多数あり、他のタスクが正常に完了した後にのみ最終タスクを完了したい。結果に対していくつかの計算を行って、代わりに処理を停止して禁止された HTTP を返す必要があるかどうかを確認します。結果。私が確信していないのは、最後の行が実際に他のすべてのタスクが完了するのを待つのか、それとも別の構造にする必要があるのか​​ ということです. もしそうなら、 if(getPlatformTask.Result... の評価を通過した場合にのみ呼び出されるように、最後の行をどのように構成する必要がありますか?

// run some tasks and then gather them here
Task.Factory.ContinueWhenAll(new Task[]{ getPlatformTask, getUserTask },
    (tasks) =>
    {
        Task.WaitAll(tasks);

        if (getPlatformTask.Result == null || getUserTask.Result == null)
        {
           return Task<HttpResponseMessage>.Factory.StartNew(() =>
           {
              return new HttpResponseMessage(HttpStatusCode.Forbidden);
           });
        }
    });

// will this line below get called before the inner task above completes?   
return base.SendAsync(request, cancellationToken);       
4

1 に答える 1

3

すべてのタスクが完了するまで現在のスレッドをブロックしたい場合は、単純に を使用できますTask.WaitAll()。継続タスクを使用する必要はありません。ただし、ブロックされたスレッドは、リソース (メモリなど) を使い果たすだけのスレッドであることに注意してください。多くの場合、スレッドをブロックする方が簡単ですが、効率は低くなります。

コードは次のようになります。

// run the tasks

Task.WaitAll(getPlatformTask, getUserTask);

// process the results

return base.SendAsync(request, cancellationToken);

いいえ、あなたのバージョンでは、すべてのタスクが完了する前に最後の行を実行できます (そしておそらく実行します)。ContinueWhenAll()ブロックしない、それが全体のポイントです。

編集:あなたのメソッドが . を返すことに気付きましたTask。したがって、実際にスレッドをブロックする必要はありません。代わりにTask、すべての作業が完了したときに完了した a を返すことができます。次のようになります。

// run the tasks

var result = Task.Factory.ContinueWhenAll(
    new[] { getPlatformTask, getUserTask },
    _ =>
    {
        // process the results

        return base.SendAsync(request, cancellationToken);
    });

return result.Unwrap();

ここでresultは ですがTask<Task<HttpResponseMessage>>、必要なのは だけTask<HttpResponseMessage>です。これを行うには、Unwrap()メソッドを使用できます。

于 2012-03-02T21:49:40.247 に答える