LoginSignup
6
8

More than 5 years have passed since last update.

Taskを使った非同期処理

Last updated at Posted at 2016-09-20

画面をフリーズさせない

非同期処理を使って、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

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8