【C#】非同期メソッドで戻り値を扱う方法(Task<T>の活用)

C# の非同期処理では async / await を利用するのが一般的です。その際、非同期メソッドから値を返すには Task<T> を使います。これにより「非同期に計算した結果を返す」ことが可能になります。本記事では Task<T> の基本と活用例を解説します。

Task<T>を戻り値にする基本

非同期メソッドの戻り値を Task<T> にすると、await で呼び出したときに T 型の値が得られます。

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        int result = await AddAsync(3, 5);
        Console.WriteLine($"計算結果: {result}");
    }

    static async Task<int> AddAsync(int a, int b)
    {
        await Task.Delay(1000); // 疑似的な非同期処理
        return a + b;
    }
}

AddAsyncTask<int> を返し、呼び出し側では awaitint の結果を受け取れます。

TaskとTask<T>の違い

Task … 戻り値を持たない非同期処理
Task<T> … 戻り値を持つ非同期処理

static async Task DoWorkAsync()
{
    await Task.Delay(500);
    Console.WriteLine("処理完了");
}

static async Task<string> GetMessageAsync()
{
    await Task.Delay(500);
    return "Hello World";
}

複数の非同期結果を扱う

Task.WhenAll を使うと、複数の非同期メソッドを並列で実行し、すべての結果をまとめて取得できます。

var tasks = new[]
{
    GetNumberAsync(1),
    GetNumberAsync(2),
    GetNumberAsync(3)
};

int[] results = await Task.WhenAll(tasks);
Console.WriteLine(string.Join(", ", results));

static async Task<int> GetNumberAsync(int n)
{
    await Task.Delay(500);
    return n * 10;
}

この例では 3 つの非同期処理が同時に動作し、すべての結果を配列として取得しています。

戻り値を即座に返す場合

非同期メソッドで計算がすぐに終わる場合、Task.FromResult を使って簡潔に記述できます。

static Task<int> GetFixedValueAsync()
{
    return Task.FromResult(42);
}

まとめ

非同期メソッドで戻り値を扱うには Task<T> を利用します。

  • Task は戻り値なし、Task<T> は戻り値あり
  • awaitT 型の結果を取り出せる
  • Task.WhenAll を使えば複数結果を効率的に処理できる
  • Task.FromResult は即時値を返す際に便利

I/O 処理や計算結果を返す非同期メソッドを設計する際は、Task<T> を使いこなすことが重要です。