画面をフリーズさせない
非同期処理を使って、5秒カウント中も画面操作(画面の移動等)を受け付けるようにする。
delegate void DelBar (int i);
private void SetBarValue(int i)
{
progressBar1.Value = i;
}
private async void button1_Click(object sender, EventArgs e)
{
progressBar1.Minimum = 0;
progressBar1.Maximum = 5;
progressBar1.Value = 0;
await Task.Run(() =>
{
for (int i = 1; i <= 5; i++)
{
Thread.Sleep(1000);
// コントロールを生成したスレッドではないスレッドから操作することはできない
// progressBar1.Value = i;
// Invokeメソッドを使う
progressBar1.Invoke(new DelBar(SetBarValue), new object[] { i });
}
});
// 5秒後に実行
Debug.WriteLine("done.");
}
非同期処理の実装方法
調査したところ、下記の3つの方法で実装できるようだ。
private void button2_Click(object sender, EventArgs e)
{
// .NET4.0~使用可
Task t1 = Task.Factory.StartNew(Worker);
// .NET4.0~使用可
Task t2 = new Task(Worker);
t2.Start();
// .NET4.5~使用可
Task t3 = Task.Run(() => Worker());
// 全てのタスクが終了するまで待機
Task.WaitAll(t1, t2, t3);
}
/// <summary>
/// ワーカスレッドで実行されるメソッドです。
/// </summary>
private void Worker()
{
for(int i=0; i<10; i++)
{
Debug.WriteLine(i);
Thread.Sleep(1000);
}
}
t3、t1、t2 の順に、使用を検討すればよいようだ。
t3 で実装するのが最も望ましいと判断した。
参照
■"Task.Factory.StartNew" vs "new Task(…).Start"
https://blogs.msdn.microsoft.com/pfxteam/2010/06/13/task-factory-startnew-vs-new-task-start/
In general, I always recommend using Task.Factory.StartNew unless the particular situation provides a compelling reason to use the constructor followed by Start.
■連載! とことん C#: 第 32 回 並列 (Parallel) で行こう
https://code.msdn.microsoft.com/windowsdesktop/32-Parallel-af4950ae