【C#】非同期タスクのキャンセル方法|CancellationTokenの基本

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 をタスクに渡してキャンセル可能にする
  • ThrowIfCancellationRequestedTask.Delay(..., token) を活用する
  • タイムアウトや複数トークンの組み合わせも可能

非同期処理を実務で使う際は、キャンセル制御を正しく組み込むことが効率的で安定したアプリケーション設計に直結します。