C# で非同期処理を実装する際、状況に応じて処理を中断したい場面があります。そのために用意されている仕組みが CancellationToken
です。キャンセルを適切に扱うことで、無駄な処理を避けて効率的かつ安全にアプリケーションを動作させられます。本記事では CancellationToken
の基本的な使い方を解説します。
CancellationTokenの基本
キャンセルを管理するには CancellationTokenSource
を使い、そこから CancellationToken
を取得して非同期タスクに渡します。キャンセルを要求すると、そのトークンを監視しているタスク側が処理を中断できます。
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var cts = new CancellationTokenSource();
var token = cts.Token;
var task = DoWorkAsync(token);
// 2秒後にキャンセル要求
await Task.Delay(2000);
cts.Cancel();
try
{
await task;
}
catch (OperationCanceledException)
{
Console.WriteLine("タスクはキャンセルされました");
}
}
static async Task DoWorkAsync(CancellationToken token)
{
for (int i = 0; i < 5; i++)
{
token.ThrowIfCancellationRequested(); // キャンセルチェック
Console.WriteLine($"処理中: {i}");
await Task.Delay(1000, token); // キャンセル可能な待機
}
}
}
キャンセルのチェック方法
タスク内では以下の方法でキャンセルを確認できます。
token.IsCancellationRequested
… キャンセル要求を確認token.ThrowIfCancellationRequested()
… 要求があれば例外を投げて処理終了Task.Delay(..., token)
やTask.Run(..., token)
などキャンセル対応 API を利用
タイムアウトを利用したキャンセル
CancellationTokenSource
は一定時間後に自動キャンセルするよう設定できます。
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
var token = cts.Token;
try
{
await DoWorkAsync(token);
}
catch (OperationCanceledException)
{
Console.WriteLine("タイムアウトでキャンセルされました");
}
複数のキャンセル要因を組み合わせる
CancellationTokenSource.CreateLinkedTokenSource
を使えば、複数のトークンをまとめて扱えます。ユーザー操作とタイムアウトを同時に監視するような場面に便利です。
var userCts = new CancellationTokenSource();
var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
// 複数のキャンセル要因を統合
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
userCts.Token, timeoutCts.Token);
await DoWorkAsync(linkedCts.Token);
まとめ
CancellationToken
を利用すると、非同期タスクを安全にキャンセルできます。
CancellationTokenSource
でキャンセル要求を発行するCancellationToken
をタスクに渡してキャンセル可能にするThrowIfCancellationRequested
やTask.Delay(..., token)
を活用する- タイムアウトや複数トークンの組み合わせも可能
非同期処理を実務で使う際は、キャンセル制御を正しく組み込むことが効率的で安定したアプリケーション設計に直結します。