【C#】Taskに引数を渡す |
しかも、引数を渡す」
を実装した時
ちょっと苦戦したので覚え書き。
「Listに10のTaskを追加。
それぞれに追加した順番の連番を引数に持たせる」という
サンプルを実装してみました。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
/// <summary>
/// Taskテスト用クラス
/// </summary>
private class TestTask
{
/// <summary>
/// Taskテスト
/// </summary>
public void Run()
{
List<Task> tasks = new List<Task>();
//Taskを10個作成
for (int count = 0; count < 10; count++)
{
Task newTask = new Task(() =>
{
//0-1000ミリ秒待つ
int sleepTime = new Random().Next(1000);
System.Threading.Thread.Sleep(sleepTime);
//引数と現在時間、Sleep時間を表示する
System.Console.WriteLine(
count.ToString() + " 経過時間:" +
DateTime.Now.ToString("HH:mm:ss.fff") +
" Sleep時間:" +
sleepTime.ToString()
);
});
tasks.Add(newTask);
}
//Taskを実行
foreach (Task task in tasks)
{
task.Start();
}
//Taskが終了するまで待つ
Task.WaitAll(tasks.ToArray());
}
}
/// <summary>
/// エントリポイント
/// </summary>
static void Main(string[] args)
{
TestTask test = new TestTask();
test.Run();
//キー入力を待ってから終了
System.Console.ReadKey();
}
}
}
実行結果例は下記の通りです
10 経過時間:23:54:00.165 Sleep時間:754
10 経過時間:23:54:00.165 Sleep時間:754
10 経過時間:23:54:00.661 Sleep時間:441
10 経過時間:23:54:00.662 Sleep時間:441
10 経過時間:23:54:01.403 Sleep時間:741
10 経過時間:23:54:01.405 Sleep時間:741
10 経過時間:23:54:01.919 Sleep時間:515
10 経過時間:23:54:01.921 Sleep時間:515
10 経過時間:23:54:02.484 Sleep時間:564
10 経過時間:23:54:02.486 Sleep時間:564
Task#Start()は遅延実行されるため、
ラムダで記述したAction内でconuntの値を取得すると
for後の値「10」を参照してしまいます。
「同一の変数を参照しているから良くないのではないか」
と思い、Taskテスト用クラス「TestTask」に
メソッド「CreateTask」を追加しました。
/// <summary>
/// Taskテスト用クラス
/// </summary>
private class TestTask
{
/// <summary>
/// Task生成メソッド
/// </summary>
/// <param name="count">引数サンプル</param>
/// <returns>Taskインスタンス</returns>
private Task CreateTask(int count)
{
return new Task(() =>
{
//0-1000ミリ秒待つ
int sleepTime = new Random().Next(1000);
System.Threading.Thread.Sleep(sleepTime);
//引数と現在時間、Sleep時間を表示する
System.Console.WriteLine(
count.ToString() + " 経過時間:" +
DateTime.Now.ToString("HH:mm:ss.fff") +
" Sleep時間:" +
sleepTime.ToString()
);
});
}
/// <summary>
/// Taskテスト
/// </summary>
public void Run()
{
List<Task> tasks = new List<Task>();
//Taskを10個作成
for (int count = 0; count < 10; count++)
{
Task newTask = this.CreateTask(count);
tasks.Add(newTask);
}
//Taskを実行
foreach (Task task in tasks)
{
task.Start();
}
//Taskが終了するまで待つ
Task.WaitAll(tasks.ToArray());
}
}
RunメソッドのforではCreateTaskメソッドを呼んで
Taskインスタンスを生成しています。
修正後の実行結果例は下記の通りです
0 経過時間:00:07:22.286 Sleep時間:66
1 経過時間:00:07:22.286 Sleep時間:66
2 経過時間:00:07:22.710 Sleep時間:369
3 経過時間:00:07:22.711 Sleep時間:369
5 経過時間:00:07:23.632 Sleep時間:920
4 経過時間:00:07:23.632 Sleep時間:920
6 経過時間:00:07:23.665 Sleep時間:446
9 経過時間:00:07:23.771 Sleep時間:105
7 経過時間:00:07:24.543 Sleep時間:910
8 経過時間:00:07:24.549 Sleep時間:910
countがユニークな値になりました。
参考になれば幸いです。
よかったらクリックしてください。
にほんブログ村