4

SignalRを使用しています。ハブ上の関数は、多くの場合、タスクを返します。これで、多数のグループに接続を追加する関数ができました。これらすべてのタスクを表すタスクを返したいと思います。

そのための完璧な関数を見つけました:Task.WhenAll。ただし、これは.NET 4.5の新機能であり、私はまだ.NET4で立ち往生しています。

そのため、.NET 4.5に移行できるようになるまで、独自のバージョンを作成することにしました。マルチスレッド(スレッドプールなど)に関しては、いくつかの注意点があることが多いため、実装が正しいかどうかはわかりません。

public static Task WhenAll(IEnumerable<Task> tasks)
{
    return Task.Factory.StartNew(() => Task.WaitAll(tasks.ToArray()));
}

機能的には機能すると思いますが、新しいタスク用に余分にブロックされたスレッドを取得しませんか?それともこれは避けられないのですか?

編集:SignalRでの使用方法は次のとおりです。

public static Task Add(this IGroupManager groupManager, string connectionId,
                                                   IEnumerable<string> groups)
{
   return WhenAll(groups.Select(group => groupManager.Add(connectionId, group)));
}
4

2 に答える 2

9

あなたの解決策はうまくいくでしょう、しかしあなたはそれがずっとスレッドをブロックするであろうということは正しいです。

WhenAll().Net 4.0に効率的に実装する最も簡単な方法は、を使用することだと思いますContinueWhenAll()Taskコレクションのすべてが終了するとアクションを実行し、Taskそのアクションを表すものを返します。それだけがTask必要なので、アクションは必要ありません。空のラムダを渡すと機能します。

public static Task WhenAll(IEnumerable<Task> tasks)
{
    return Task.Factory.ContinueWhenAll(tasks.ToArray(), _ => {});
}
于 2012-09-20T14:54:20.010 に答える
5

.Net 4.0をターゲットにしているときに、VS2012を使用できる場合、より簡単で優れたオプション(IMHO)は、NuGetを使用して非同期ターゲットパックをインストールし、 WhenAll(この場合はTaskEx.WhenAll)を使用することです。 4.0フレームワークにあるタスクを変更することはできません)。

重要な追加ボーナスとして、.Net4.0コードでもasync/awaitを使用できます:)

于 2012-09-20T15:23:35.633 に答える