読者です 読者をやめる 読者になる 読者になる

プログラムの事とか

お約束ですが「掲載内容は私個人の見解です」

非同期処理の戻り値をまとめて待ちたい

C#

基本は分かったつもりになっていても、相変わらず少し複雑になるとよくわからない私です。

C#にasync/awaitが追加されたのは何年前だったでしょうか。みなさん当たり前のように使っているとおもいます。 私だって使ってます。

static async Task<bool> IsEven(int num)
{
    await Task.Delay(5000);
    return num % 2 == 0;
}

上は5秒かけて入力値が偶数なのかを返す非同期の関数です。

コンソールアプリで

static void Main(string[] args)
{
    Task.Run(async () =>
    {
        var number = 2;
        var even = await IsEven(number);
        Console.WriteLine(even ? "Even" : "Odd");
    });
    Console.ReadKey();
}

って感じで呼べば5秒後にEvenと画面に出てきます。

複数同時に実行してその戻り値を処理したい

複数の数値を上の関数にかけて偶数と奇数の数を求めてみようと思います。

Task.Runの中身を下のように書き換えました。

var numbers = new[] { 2, 4, 6, 9 };
var resultList = new List<bool>();
foreach (var task in numbers.Select(IsEven).ToArray())
{
    resultList.Add(await task);
}
Console.WriteLine($"Even {resultList.Count(r => r)}, Odd {resultList.Count(r => !r)}");

4種類の数値を非同期に処理しているので5秒後に結果がわかります。 非同期すごい。

ちなみにforeach行のToArray()を削ると20秒かかります。 理由はLinqってそういうものだからとかそんな感じでお茶を濁しましょう。(本題と離れているし)

一応求める機能は実装できたんですが、List作って順番に結果を入れて・・・とかいかにも私が作りそうな感じの残念さを醸し出していて残念です。 頼みのR#先生も何もヒントくれませんので私の力ではこれが限界でした。

こころやさしい通りすがりのどなたか、もっといい書き方があったら教えてくれませんか・・・