CancellationTokenSource の必要性が分からない…。
Task をキャンセルするサンプルソース
※Microsoft 公式のものを少し手直ししたもの
using System.Threading.Tasks; class Program { static void Main() { // これ使うのめんどくさくね? var cts = new CancellationTokenSource(); var ct = cts.Token; var task = Task.Run(()=>{ // これ ct がスコープにいないとき受け渡せなくね? // 手動で止めるんだったら ct じゃなくてもよくね? while (!ct.IsCancellationRequested) { /* 処理 */ } }); // ここから下はわりとどうでもいい while (!task.IsCompleted && !task.IsCanceled) { Console.WriteLine("処理中…"); Thread.Sleep(3000); cts.Cancel(); // キャンセルしても task が勝手に止まってくれるわけじゃない } Console.WriteLine("finished"); } }
CancellationTokenSource と CancellationToken を使わない方法に置き換えたコード
using System.Threading.Tasks; class Program { static void Main() { bool is_canceled = false; var task = Task.Run(() => { while (is_canceled) { /* 処理 */ } }); while (!task.IsCompleted && !is_canceled) { Console.WriteLine("処理中…"); Thread.Sleep(3000); is_caneled = true; } Console.WriteLine("finished"); } }
「bool でいいじゃん」という話。
キャンセラなんとかソース使わないとダメそうなケース
これも Microsoft 公式にあったサンプルソース
そのままコピペしても動かないので、最低限ビルド通るように手直しした
using System.Threading.Tasks; class Example { static CancellationTokenSource cts = new (); static TaskFactory factory = new (cts.Token); static void Main() { var t2 = factory.StartNew(() => DoWork()); Thread.Sleep(1000); cts.Cancel(); // 1秒経過したら問答無用でキャンセル } static void DoWork() { /* 処理 */ } }
TaskFactory を使う場合は受け渡しが楽なのと、cts.Cancel() でタスクが止まってくれるので、キャンセラなんたらソースは TaskFactory 用と考えた方が良さそう。