CancellationTokenパターンと協調的キャンセル
CancellationTokenを渡して適切に扱います。CTSを作成し、キャンセルをポーリング・スローし、非同期APIに渡し、登録を解除して後始末します。
「CancellationTokenパターンと協調的キャンセル」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン1/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全3レッスンが含まれています。
協調的なキャンセル
目的:作業を協調的にキャンセルします。
- CancellationTokenSourceを作成します
- CancellationTokenを下位へ渡します
- IsCancellationRequestedを確認するか、ThrowIfCancellationRequested()を呼び出します
- キャンセルを迅速かつ適切に処理します
呼び出し元主導のキャンセル
CancellationTokenSourceを作成し、トークンを渡して、呼び出し元からキャンセルします。呼び出し先はOperationCanceledExceptionをスローします。
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task WorkAsync(CancellationToken ct)
{
// Poll occasionally; throw to end cooperatively
for (int i = 0; i < 5; i++)
{
ct.ThrowIfCancellationRequested();
Console.WriteLine("Step " + i);
await Task.Delay(100, ct); // pass token to async API
}
}
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
Task t = WorkAsync(cts.Token);
// Cancel after a short delay (simulated user action)
Thread.Sleep(180);
cts.Cancel();
try
{
t.GetAwaiter().GetResult();
}
catch (OperationCanceledException)
{
Console.WriteLine("Canceled!");
}
}
}
トークンの転送
すべての非同期レイヤーを通じてトークンを転送し、内部の呼び出しが速やかに停止できるようにします。
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task<string> FetchAsync(CancellationToken ct)
{
await Task.Delay(80, ct); // pretend I/O
ct.ThrowIfCancellationRequested();
return "data";
}
static async Task<string> ProcessAsync(CancellationToken ct)
{
string raw = await FetchAsync(ct); // forward token
await Task.Delay(80, ct);
return raw.ToUpperInvariant();
}
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
Task<string> job = ProcessAsync(cts.Token);
cts.CancelAfter(100); // schedule a cancellation
try
{
Console.WriteLine(job.GetAwaiter().GetResult());
}
catch (OperationCanceledException)
{
Console.WriteLine("Pipeline canceled");
}
}
}
token.Register によるクリーンアップ
token.Registerを使用して、キャンセルが要求されたときに実行される小さなクリーンアップ処理を登録します。
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task UseRegistrationAsync(CancellationToken ct)
{
using (ct.Register(() => Console.WriteLine("Cleanup: releasing temp resources")))
{
for (int i = 0; i < 3; i++)
{
ct.ThrowIfCancellationRequested();
await Task.Delay(120, ct);
Console.WriteLine("Tick " + i);
}
}
}
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
Task t = UseRegistrationAsync(cts.Token);
Thread.Sleep(150);
cts.Cancel();
try { t.GetAwaiter().GetResult(); }
catch (OperationCanceledException) { Console.WriteLine("Canceled with cleanup"); }
}
}
リンクされたソース
CreateLinkedTokenSourceは、複数のシグナル(例:ユーザーによるキャンセルとタイムアウト)を1つのトークンにまとめます。
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task WorkAsync(CancellationToken ct)
{
await Task.Delay(500, ct);
Console.WriteLine("Finished work");
}
public static void Main(string[] args)
{
var parent = new CancellationTokenSource();
var timeout = new CancellationTokenSource();
timeout.CancelAfter(200);
// Link both sources: cancel if parent OR timeout requests
var linked = CancellationTokenSource.CreateLinkedTokenSource(parent.Token, timeout.Token);
Task t = WorkAsync(linked.Token);
try { t.GetAwaiter().GetResult(); }
catch (OperationCanceledException) { Console.WriteLine("Canceled by parent/timeout"); }
finally { linked.Dispose(); parent.Dispose(); timeout.Dispose(); }
}
}
ベストプラクティス
ヒント:
- 非同期 API(Task.Delay、I/O)にトークンを渡し、速やかに停止できるようにします。
- 作業を終了するにはOperationCanceledExceptionをスローし、握りつぶさないでください。
- タイマーや登録を所有する場合は、CancellationTokenSourceを破棄します。
- ハンドラーは高速に保ち、Register内では最小限の処理だけを行います。
協調的キャンセルのルール
まとめ
まとめ:キャンセルを協調的に行うため、トークンを渡し、ポーリングまたはThrowIfCancellationRequestedを使用し、小さなクリーンアップ処理を登録し、複数のシグナルをまとめる場合はソースをリンクします。
よくある質問
「CancellationTokenパターンと協調的キャンセル」レッスンは無料ですか?
はい。「CancellationTokenパターンと協調的キャンセル」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全3レッスンが含まれています。
「CancellationTokenパターンと協調的キャンセル」で何を学びますか?
CancellationTokenを渡して適切に扱います。CTSを作成し、キャンセルをポーリング・スローし、非同期APIに渡し、登録を解除して後始末します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/3です。
「CancellationTokenパターンと協調的キャンセル」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- CancellationTokenパターンと協調的キャンセル
- タイムアウト、IProgress 、非同期破棄(エミュレーション)
- レジリエンスの基礎:リトライとバックオフ