【C#】非同期LINQ(System.Linq.Async)の活用方法
C# では LINQ を使ってコレクションを効率的に操作できますが、通常の LINQ は同期処理に限られます。データベースや外部 API など非同期でデータを取得する場合は System.Linq.Async
パッケージを活用すると便利です。本記事では、非同期 LINQ の基本的な使い方と注意点を紹介します。
System.Linq.Asyncとは
System.Linq.Async
は Microsoft が提供する拡張ライブラリで、非同期ストリーム (IAsyncEnumerable<T>
) に対して LINQ ライクな操作を可能にします。
NuGet パッケージとして提供されており、次のコマンドでインストールできます。
dotnet add package System.Linq.Async
IAsyncEnumerableの基本
IAsyncEnumerable<T>
は非同期に列挙できるコレクションです。await foreach
を使ってデータを順次処理できます。
async IAsyncEnumerable<int> GetNumbersAsync()
{
for (int i = 1; i <= 5; i++)
{
await Task.Delay(500); // 疑似的な非同期処理
yield return i;
}
}
await foreach (var n in GetNumbersAsync())
{
Console.WriteLine(n);
}
非同期LINQ拡張メソッドの利用
System.Linq.Async
を導入すると、Where
・Select
・ToListAsync
など非同期対応のメソッドを使えます。
using System.Linq;
using System.Linq.Async;
// フィルタリングと投影を非同期に処理
var results = await GetNumbersAsync()
.Where(n => n % 2 == 0)
.Select(n => n * 10)
.ToListAsync();
Console.WriteLine(string.Join(", ", results)); // 20, 40
代表的な非同期LINQメソッド
ToListAsync()
… 非同期列挙をリストに変換FirstAsync()
/FirstOrDefaultAsync()
… 最初の要素を取得SingleAsync()
/SingleOrDefaultAsync()
… 単一要素を取得CountAsync()
… 件数を非同期でカウントAnyAsync()
… 条件を満たす要素が存在するか判定
データベースとの連携例
Entity Framework Core などでは、IQueryable
に対して ToListAsync
や FirstOrDefaultAsync
を使うのが一般的です。非同期で DB クエリを実行できるため、アプリ全体の応答性が向上します。
using Microsoft.EntityFrameworkCore;
var users = await dbContext.Users
.Where(u => u.IsActive)
.OrderBy(u => u.Name)
.ToListAsync();
注意点
IAsyncEnumerable
はawait foreach
でしか列挙できない- 非同期 LINQ は非同期メソッド内でのみ利用可能
- データベースアクセス時は必ず
ToListAsync
などでawait
する必要がある
まとめ
System.Linq.Async
を利用すると、非同期ストリームやデータベース操作に LINQ を自然に組み込めます。
IAsyncEnumerable<T>
に対して LINQ メソッドが利用可能ToListAsync
やCountAsync
などで非同期にデータを処理できる- Entity Framework Core と組み合わせれば DB アクセスを効率化可能
非同期 LINQ を使いこなすことで、モダンな C# アプリケーションのパフォーマンスと可読性を向上できます。