はじめに
この記事ではC#のTaskを用いた非同期処理の書き方を初心者向けに解説します。
家事の洗濯と料理を例にあげて感覚的に非同期処理と同期処理がわかるように紹介しています。
処理の前提
- 洗濯と料理は同時並行で進められるものとします(非同期処理)。
- 洗濯は一度洗濯機に衣類を入れてスイッチを押してしまえば自動で洗濯してくれます。
- 料理は焼いている間は焼き上がるまで特にやることはありません。
- それぞれの作業工程は一つ目の工程が終わってからでないと着手できません(同期処理)。
- 洗濯は一度洗濯機に衣類を入れてスイッチを押してしまえば自動で洗濯してくれます。
- 料理は焼いている間は焼き上がるまで特にやることはありません。
つまり、洗濯と料理を同時並行で家事をはじめて、終わった物からそれぞれの次の工程に進みます。
例
program.cs
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Sample
{
class Program
{
static Task Main(string[] args)
{
// 洗濯と料理は非同期処理
// 洗濯の作業
Task<string> washing = wash();
// 料理の作業
Task<string> cooking = cook();
// 結果を出力
Console.WriteLine(washing.Result);
Console.WriteLine(cooking.Result);
return Task.CompletedTask;
}
// 洗濯と料理のそれぞれの工程は同期処理
// 洗濯
static async Task<string> wash()
{
Console.WriteLine("【洗濯①】洗濯開始");
await Task.Delay(5000);
Console.WriteLine("【洗濯①】洗濯 終了");
Console.WriteLine("【洗濯②】乾燥 開始");
await Task.Delay(2000);
Console.WriteLine("【洗濯②】乾燥 終了");
return "洗濯完了";
}
// 料理
static async Task<string> cook()
{
Console.WriteLine("【料理①】味付け 開始");
await Task.Delay(2000);
Console.WriteLine("【料理①】味付け 終了");
Console.WriteLine("【料理②】焼く 開始");
await Task.Delay(4000);
Console.WriteLine("【料理②】焼く 終了");
return "料理完了";
}
}
}
実行結果
【洗濯①】洗濯開始
【料理①】味付け 開始
【料理①】味付け 終了
【料理②】焼く 開始
【洗濯①】洗濯 終了
【洗濯②】乾燥 開始
【料理②】焼く 終了
【洗濯②】乾燥 終了
洗濯完了
料理完了
コード解説
static async Task
- Mainメソッドの中でasyncメソッドを使うおまじない
async / await
- 非同期にしたい処理を含むメソッドは修飾子asyncをつける
- 非同期にしたい処理にはawaitをつけて実行する
※awaitは戻り値がTask型のメソッドにしか付けられない - awaitがついているメソッドが実行されると、そのメソッドを抜けて呼び出し元(Mainメソッド)に戻る
Task
- taskの戻り値はTask型もしくはTask型のジェネリックにする
- Delayプロパティは引数で指定した秒数を待ち、その実行状態をTask型で返す非同期メソッド
- Resultプロパティで戻り値を取得できる
参考
多分わかりやすいC#の非同期処理その2 〜 asyncとawait 〜
Task.CompletedTask プロパティ
C# 非同期、覚え書き。