ちいさな Tips。サンプルでよく使いますが、しばらく止まって欲しいときってありますよね。そのケースに、Thread.Sleep とかよく使うようです。ただ、これは、あまり使わないほうが良さげですね。
例えば次のようなサンプルを書いてみました。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AwaitSample
{
class Program
{
async Task<string> getMessageAsync(string message)
{
Console.WriteLine("getMessage!");
System.Threading.Thread.Sleep(3000);
Console.WriteLine("finished!");
return "message:" + message;
}
async void executeAsync()
{
Console.WriteLine("step 1");
var result = await getMessageAsync("hello");
Console.WriteLine(result);
Console.WriteLine("step 2");
}
static void Main(string[] args)
{
var program = new Program();
program.executeAsync();
Console.WriteLine("step 3");
Console.ReadLine();
}
}
}
結果は step 1, 2, 3 が順に実行されてしまいます。私の想定では、step 1, getMessage! の後は、executeAsync() は非同期なので、先に step 3 が表示されると思っていました。
step 1
getMessage!
finished!
message:hello
step 2
step 3
理由は簡単で、Thread.Sleep Method は、スレッドを止めるメソッドだから、スレッドがブロックされます。だから、この非同期処理が、メインと同じスレッドを使っているとしたら、メイン側のスレッドも停止します。
この場合は、TaskDelay()
メソッドを使ってみます。Task.Delay Method (TimeSpan, CancellationToken) こちらは特定の時間の後、Taskの実行が終了しますので、スレッドをブロックしません。
// System.Threading.Thread.Sleep(3000);
await Task.Delay(3000);
step 1
getMessage!
step 3
finished!
message:hello
step 2
めでたしめでたし。