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 用と考えた方が良さそう。

