すぐに開始できる他の独立したタスクのコレクションを作成する独立したタスクのコレクションがあるコードをよく使用するため、時間的には次のようになります。
A0 -------
B0 --------- C0 --------- ...
B1 ------ C1 ------------ ...
B2------------------- C2 ...
A1 ---
B3 -------- C3--------------- ...
B4 -- C4 ------------------- ...
私がしていることは通常、次のようなネストされたメソッドを持っていることです
.
.
.
await Task.WhenAll(A0, A1)
.
.
.
private static async ExecuteA(Task A)
{
var results = await A;
var BsS = results.Select(r => ExecuteBC(r));
await Task.WhenAll(BCs);
private static async ExecuteBC(string value)
{
var result = await ExecuteB(value);
await ExecuteC(result);
}
ネストされた非同期タスクをチェーンするためのよりエレガントな方法はありますか?
私はあなたの基本的なサンプルコードを取り、それが結果を生み出すまでそれを具体化しました:
async Task Main()
{
string[] a0_source = new[] { "Hello", "World" };
string[] a1_source = new[] { "Hi", "There" };
Task<string[]> A0 = ExecuteA(a0_source);
Task<string[]> A1 = ExecuteA(a1_source);
var results = await Task.WhenAll(A0, A1);
var output = String.Join(", ", results.SelectMany(x => x));
Console.WriteLine(output);
}
private static async Task<string[]> ExecuteA(string[] A)
{
var BCs = A.Select(r => ExecuteBC(r));
return await Task.WhenAll(BCs);
}
private static async Task<string> ExecuteBC(string value)
{
var result = await ExecuteB(value);
return await ExecuteC(result);
}
private static async Task<string> ExecuteC(string value)
{
return await Task.Run(() => value + "!C");
}
private static async Task<string> ExecuteB(string value)
{
return await Task.Run(() => value + "!B");
}
これHello!B!C, World!B!C, Hi!B!C, There!B!C
はコンソールで生成されます。
次に、MicrosoftのReactive Framework(NuGet "System.Reactive")を導入し、次の中間結果を生成しました。
async Task Main()
{
string[] a0_source = new[] { "Hello", "World" };
string[] a1_source = new[] { "Hi", "There" };
IObservable<string> query =
from a in a0_source.Concat(a1_source).ToObservable()
from b in Observable.FromAsync(() => ExecuteB(a))
from c in Observable.FromAsync(() => ExecuteC(b))
select c;
var output = String.Join(", ", await query.ToArray());
Console.WriteLine(output);
}
private static async Task<string> ExecuteC(string value)
{
return await Task.Run(() => value + "!C");
}
private static async Task<string> ExecuteB(string value)
{
return await Task.Run(() => value + "!B");
}
次に、それをさらに一歩進めて、これを行うことができます。
async Task Main()
{
string[] a0_source = new[] { "Hello", "World" };
string[] a1_source = new[] { "Hi", "There" };
IObservable<string> query =
from a in a0_source.Concat(a1_source).ToObservable()
from b in Observable.Start(() => a + "!B")
from c in Observable.Start(() => b + "!C")
select c;
var output = String.Join(", ", await query.ToArray());
Console.WriteLine(output);
}
今はかなりエレガントに見えます。最良の点は、簡単な.ToTask()
呼び出しでオブザーバブルをタスクに簡単に変換できることです。オブザーバブルも待っています。交換が簡単で、よりエレガントです。最良の点は、LINQ構文も使用していることです。さらに説明が必要な場合はお知らせください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加