Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

C#辞典

  1. トップページ
  2. C#辞典
  3. Task.FromResult() / CancellationToken

Task.FromResult() / CancellationToken

既に結果が確定している Task を作成する『Task.FromResult()』と、非同期処理をキャンセルするための『CancellationToken』の使い方です。

構文
using System;
using System.Threading;
using System.Threading.Tasks;

// 既に完了した Task<TResult> を作成します(await 不要の即時完了タスク)。
Task<TResult> task = Task.FromResult<TResult>(result);

// キャンセル要求を発行する送信側(CancellationTokenSource)を作成します。
CancellationTokenSource cts = new CancellationTokenSource();

// 受信側(CancellationToken)を取得して非同期メソッドに渡します。
CancellationToken token = cts.Token;

// キャンセルを要求します(Cancel() を呼ぶと token.IsCancellationRequested が true になります)。
cts.Cancel();

// キャンセルされていた場合に OperationCanceledException をスローします。
token.ThrowIfCancellationRequested();
メソッド一覧
メソッド / プロパティ概要
Task.FromResult(result)指定した値を結果として持つ、既に完了した Task<TResult> を返します。
Task.CompletedTask既に完了した Task(戻り値なし)を返します。Task.FromResult(0) の代替として使用します。
CancellationTokenSource.Cancel()キャンセル要求を発行します。Token の IsCancellationRequested が true になります。
CancellationTokenSource.CancelAfter(ms)指定ミリ秒後に自動的にキャンセルを発行します。タイムアウト処理に使用します。
CancellationToken.IsCancellationRequestedキャンセルが要求されていれば true を返します。
CancellationToken.ThrowIfCancellationRequested()キャンセルされていれば OperationCanceledException をスローします。
サンプルコード
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    // Task.FromResult() の使用例 — インターフェースの同期的な実装に便利です。
    static Task<int> GetCachedValueAsync(bool useCache)
    {
        if (useCache)
        {
            // キャッシュから即座に返す場合は Task.FromResult() を使います。
            return Task.FromResult(42);
        }
        return Task.Run(() => 42); // 本来の非同期処理
    }

    // CancellationToken を受け取る非同期メソッドです。
    static async Task LongRunningTaskAsync(CancellationToken token)
    {
        for (int i = 1; i <= 5; i++)
        {
            // キャンセルされていたら OperationCanceledException をスローします。
            token.ThrowIfCancellationRequested();

            Console.WriteLine($"処理中... {i}/5");
            await Task.Delay(500, token); // Delay にも token を渡します。
        }
        Console.WriteLine("処理完了");
    }

    static async Task Main()
    {
        // Task.FromResult() のサンプルです。
        int 結果 = await GetCachedValueAsync(true);
        Console.WriteLine($"キャッシュ値: {結果}");

        // CancellationToken のサンプル — 2秒後に自動キャンセルします。
        using CancellationTokenSource cts = new CancellationTokenSource();
        cts.CancelAfter(1200); // 1.2秒後にキャンセルします。

        try
        {
            await LongRunningTaskAsync(cts.Token);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("処理がキャンセルされました。");
        }
    }
}
概要

『Task.FromResult()』はインターフェースの実装でメソッドシグネチャが Task<T> を要求するが、実際には同期的に値を返したい場合に役立ちます。戻り値なしの場合は Task.CompletedTask を使用してください。

『CancellationTokenSource』は必ず using ブロックで囲むか、Dispose() を呼び出してリソースを解放してください。キャンセル後に同じ CancellationTokenSource を再利用することはできません。再度キャンセル可能な処理を行う場合は新しいインスタンスを作成してください。非同期処理の基礎についてはasync / awaitを、タスクの実行と遅延についてはTask.Run() / Task.Delay()をご確認ください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。