Timerって便利だけれども
Windows FormアプリケーションではTimerコンポーネントがあるので一定間隔の処理を行うのは便利ですね。
ただし、このTimerはGUIスレッドで動作するので、重い処理を実行するとGUIのイベントループも止まってしまうために、ウィンドウが動かせなかったりします。
以下だと、10秒間固まってしまうわけです。
private void timerHoo_Tick(object sender, EventArgs e)
{
Thread.Sleep(10000);
}
間違った解決
それを嫌ってタスクに処理を任せたくなるわけですが、それにも問題があります。
private void timerHoo_Tick(object sender, EventArgs e)
{
Debug.WriteLine("start");
Task.Run(() =>
{
Debug.WriteLine("thread start");
Thread.Sleep(10000);
Debug.WriteLine("thread end");
});
Debug.WriteLine("end");
}
これを実行するとタスク生成だけしてTick関数がさっさと抜けていき、Timer間隔が短いと次々とタスクが生成されてしまいます。
start
end
thread start
start
end
thread start
start
end
thread start
start
end
thread start
thread end // <-いつの???
async/await で解決
そこで登場するのが C#5.0 から使える async/await ですね。
private async void timerHoo_Tick(object sender, EventArgs e)
{
Debug.WriteLine("start");
await Task.Run(() =>
{
Debug.WriteLine("thread start");
Thread.Sleep(10000);
Debug.WriteLine("thread end");
});
Debug.WriteLine("end");
}
平和です。
start
thread start
thread end
end
start
thread start
thread end
end
start
thread start
thread end
end
お詳しい解説はこちら。