調べた限り、Taskを使用するのはよくないと思われます。
確認した結果、スレッドを使用するのが良いかと存じます。
注意点としては以下の通り。
- スレッド生成にはコストがかかる
ので、大量に動かす場合などは、ThreadPoolを使用する
- スレッド内の例外は自分でハンドリングすること(Abortの際に呼び出し側で例外が発生することがある)
Program.cs
1var sw = Stopwatch.StartNew();
2Console.WriteLine("[{0}]starting", sw.Elapsed);
3var thread = new Thread(new ThreadStart(() => {
4 for (var i = 0; i < 100; i++)
5 {
6 Thread.Sleep(1000);
7 Console.WriteLine("[{0}]waiting... {1}", sw.Elapsed, i);
8 }
9 Console.WriteLine("[{0}]done", sw.Elapsed);
10}));
11thread.Start();
12Console.WriteLine("[{0}]started", sw.Elapsed);
13// タスクが完了(キャンセル)するまで待つ
14Thread.Sleep(10 * 1000);
15// スレッドが生きている場合、中断する
16if (thread.IsAlive)
17{
18 Console.WriteLine("[{0}]fire abort", sw.Elapsed);
19 thread.Abort();
20}
21Console.WriteLine("[{0}]task finished", sw.Elapsed);
22sw.Stop();
23Console.ReadKey();
24
添付資料
失敗例を上げておきます。想定では途中で例外が発生し、タスクが中断のはずが、動き続けます。
Program.cs
1var sw = Stopwatch.StartNew();
2Console.WriteLine("[{0}]starting", sw.Elapsed);
3using (var cts = new CancellationTokenSource())
4using (var task = Task.Factory.StartNew(() =>
5{
6 for (var i = 0; i < 100; i++)
7 {
8 Thread.Sleep(1000);
9 Console.WriteLine("[{0}]waiting... {1} {2}", sw.Elapsed, i, cts.Token.IsCancellationRequested);
10 }
11 Console.WriteLine("[{0}]done", sw.Elapsed);
12}, cts.Token)
13)
14{
15 Console.WriteLine("[{0}]started", sw.Elapsed);
16 if (!task.Wait(10 * 1000))
17 {
18 Console.WriteLine("[{0}]fire abort", sw.Elapsed);
19 //キャンセルを伝え、直ちに例外を発生させる
20 cts.Cancel(true);
21 }
22 // タスクが完了(キャンセル)するはず
23 Console.WriteLine("[{0}]task finished", sw.Elapsed);
24 Thread.Sleep(1000);
25 //ここを抜けるときに例外発生(InvalidOperation、タスクが止まらない)
26}
[00:00:00.0001531]starting
[00:00:00.0358243]started
[00:00:01.0408594]waiting... 0 False
[00:00:02.0419494]waiting... 1 False
[00:00:03.0422047]waiting... 2 False
[00:00:04.0425413]waiting... 3 False
[00:00:05.0429124]waiting... 4 False
[00:00:06.0433045]waiting... 5 False
[00:00:07.0439868]waiting... 6 False
[00:00:08.0447972]waiting... 7 False
[00:00:09.0456474]waiting... 8 False
[00:00:10.0386241]fire abort
[00:00:10.0388371]task finished
[00:00:10.0459762]waiting... 9 True
[00:00:11.0516456]waiting... 10 True