Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
キャンセル可能な Async メソッドの使い方
[TestMethod]
public void LongTimeMethodAsyncTest2_CancellationToken付き()
{
Stopwatch sw = Stopwatch.StartNew();
CancellationTokenSource cts = new CancellationTokenSource();
Task<int> task = LongTimeLogicSample.LongTimeMethodAsync(1, cts.Token);
sw.Stop();
//Assert.AreEqual<long>(0, sw.ElapsedMilliseconds);
Assert.IsTrue(200L > sw.ElapsedMilliseconds); //実際にはせいぜい 数mSec 程度
Assert.IsFalse(task.IsCompleted, "メソッド呼び出し直後"); //非同期実行中
sw.Restart();
Thread.Sleep(500);
cts.Cancel(); // ← キャンセルをリクエスト
try
{
task.Wait(cts.Token);
// キャンセルして、Wait() にトークンを渡すと、OperationCanceledException が発生する。
Assert.Fail("キャンセル失敗");
}
catch (OperationCanceledException) {
// OK!
}
try
{
int result = task.GetAwaiter().GetResult(); // ← 非同期実行結果の取出し (非同期実行が終わるまでブロックされる)
// ↑ ここで OperationCanceledException が発生する! (そうなるように、ロジック側で ThrowIfCancellationRequested を投げている)
Assert.Fail("非同期実行結果が取れてしまった! キャンセルしたなら、取れるのはヘンだ。");
}
catch (OperationCanceledException)
{
// OK!
}
sw.Stop();
//Assert.AreEqual<long>(0, sw.ElapsedMilliseconds);
Assert.IsTrue(2000L > sw.ElapsedMilliseconds); //キャンセル出来たら1秒ちょっとで終わる
Assert.IsTrue(task.IsCompleted); //タスクはコンプリートしている
Assert.IsTrue(task.IsCanceled); //タスクはキャンセルされた
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment