なんだかGoodVibes

日々の勉強メモです。

【C#】非同期処理のキャンセル(CancellationToken)

こんにちは。
本日はC#メモです。

概要

非同期処理をキャンセルする方法に
CancellationTokenというものがあります。
本記事では、CancellationTokenを使用して
非同期処理をキャンセルする方法を記載します。


サンプルコード

以下のコードは、
指定回数分ループを行いループ回数と時間を表示します。

指定時間分待機した後、キャンセルを行っています。

public async Task Run()
{
    var cts = new CancellationTokenSource();
    var token = cts.Token;
    var task = Task.Run(() => HeavyProc(10, token), token);

    Thread.Sleep(TimeSpan.FromMilliseconds(5000));
    Console.WriteLine("Cancel!");
    cts.Cancel();

    try
    {
        await task;
    }
    catch (OperationCanceledException ex)
    {
        Console.WriteLine($"[OperationCanceledException] message: {ex.Message}");
    }
    finally
    {
        cts.Dispose();
    }
}

public void HeavyProc(int count, CancellationToken ct)
{
    if (ct.IsCancellationRequested)
    {
        Console.WriteLine("Cancelled!");
        ct.ThrowIfCancellationRequested();
    }

    for (var i = 0; i < count; i++)
    {
        Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] count = {i + 1}");
        if (ct.IsCancellationRequested)
        {
            Console.WriteLine("Cancelled!");
            ct.ThrowIfCancellationRequested();
        }

        Thread.Sleep(TimeSpan.FromMilliseconds(1000));
    }
}


var cts = new CancellationTokenSource();
var token = cts.Token;

CancellationTokenSource は
名前空間 System.Threading に含まれるクラスです。
本クラスを使用して非同期処理のキャンセルが実現できます。

.NET Framework 4から使用可能です。

上記の2行目にて CancellationToken を取得しています。

cts.Cancel();

Cancel メソッドを呼び出し、処理をキャンセル要求をしています。


HeavyProc メソッドでは、もらった CancellationToken を使用して
キャンセルの判定等を行います。

IsCancellationRequested プロパティを使用して
対象のトークンに対してキャンセルが要求されたかどうかを取得します。
キャンセル要求されている場合は true、それ以外の場合は falseとなります。


ThrowIfCancellationRequested メソッドを使用して
OperationCanceledException を発生させて処理を終了します。


実行結果は以下となります。

[16:53:28] count = 1
[16:53:30] count = 2
[16:53:31] count = 3
[16:53:32] count = 4
[16:53:33] count = 5
Cancel!
[16:53:34] count = 6
Cancelled!
[OperationCanceledException] message: The operation was canceled.



以上です。