C#の学習、いよいよ終盤です!
前回はデータ操作を効率化する LINQ を学びました。今回は、現代のアプリケーション開発で必須の概念である「非同期プログラミング」について、C#独自の機能である async
と await
キーワードを中心に解説します。
15. 非同期プログラミング (async
と await
)
非同期処理とは、時間のかかる処理(ファイルの読み書き、ネットワーク通信、データベースへのアクセスなど)を実行する際に、その処理が完了するのを待たずに、メインプログラム(UIなど)をブロックせずに次の作業に進める仕組みです。
C#では、async
と await
の組み合わせを使うことで、非同期処理を同期処理を書くのと同じくらいシンプルに記述できます。
🔄 同期と非同期の違い(料理の例)
処理の種類 | 説明 | 例(料理) |
同期処理 | 処理Aが完了するまで、次の処理Bは絶対に開始しない。 | スープ(処理A)ができるまで、他のすべての作業(肉を切る、野菜を洗うなど)を中断して待つ。 |
非同期処理 | 処理Aを開始したら、結果を待たずに次の処理Bを開始する。 | スープの火をつけたら(処理Aを開始)、**「沸いたら教えて」**と指示を出し、その間に肉を切る(処理B)。 |
Google スプレッドシートにエクスポート
🔑 async
と await
の役割
async
(非同期メソッドの宣言):- メソッドの戻り値の前に付けます。このメソッド内で
await
が使えるようになります。 - 戻り値の型は、通常
Task
またはTask<T>
(T
は結果の型)にする必要があります。
- メソッドの戻り値の前に付けます。このメソッド内で
await
(待機ポイントの指定):- 時間のかかる非同期操作の直前に付けます。
await
が実行されると、呼び出し元のメソッドは一時停止し、CPUリソースを他の作業(UIの更新など)に解放します。- 非同期処理が完了すると、
await
の次の行から処理が再開されます。
💡 非同期処理の具体的なコード例
ここでは、Task.Delay
(指定時間待機する非同期メソッド)を使って、時間のかかるネットワーク通信をシミュレーションします。
C#
using System.Threading.Tasks;
// 1. メソッドを async で宣言し、戻り値を Task にする
public async Task DownloadDataAsync()
{
System.Console.WriteLine("データダウンロードを開始します...");
// 2. await で非同期処理の結果を待つ
// 処理が一時停止し、その間メインスレッドはブロックされない
await Task.Delay(3000); // 3秒間待機(非同期操作をシミュレーション)
// 3. 待機が終わり次第、次の行から処理が再開される
System.Console.WriteLine("データダウンロードが完了しました。");
// もし結果を返すなら Task<string> とし、 return "結果データ"; と記述する
}
// メインメソッドからの呼び出し例
public static async Task Main() // Mainメソッドもasyncにすることが多い
{
System.Console.WriteLine("アプリケーション開始");
// 非同期メソッドを呼び出す
await DownloadDataAsync();
System.Console.WriteLine("アプリケーション終了");
}
/*
実行結果のイメージ:
1. アプリケーション開始
2. データダウンロードを開始します...
(3秒間、他の処理が可能になる)
3. データダウンロードが完了しました。
4. アプリケーション終了
*/
重要なルール
await
はasync
メソッド内でしか使えません。async
メソッドの戻り値は、結果を返さないならTask
、結果を返すならTask<T>
、例外的にイベントハンドラーなどの場合はvoid
にします。- 非同期メソッドは、名前に慣習として
Async
を付けて区別します(例:GetDataAsync
)。
非同期プログラミングは、特にWebアプリケーション(ASP.NET Core)やデスクトップアプリケーション(WPF, WinForms)で、ユーザーインターフェースを固まらせないために必須の技術です。
これでC#の基礎的ながらも実用性の高い主要なトピックは一通り網羅できました。これらの知識があれば、C#を使った様々な開発プロジェクトに挑戦できる土台ができています。