この回答は、@svick のコメントに基づいています。
メソッドのすべての「作業」を呼び出し元と同じスレッドで実行したいが、キャンセルの目的でスレッド プール スレッドが使用されても構わないと仮定します (I' mは、タイマーが起動したときにスレッド プール スレッドを使用しますTask.Delay
。Timer
Task
とはいえ、メソッドが返されたときに Task が完了したことが確実にわかるため、 は必要ありません。タイムアウトのある通常の方法だけで十分です。
static void DoSomethingOrThrowAfterTimeout(int millisecondsTimeout)
{
CancellationTokenSource cts = new CancellationTokenSource(millisecondsTimeout);
CancellationToken ct = cts.Token;
// do some work
ct.ThrowIfCancellationRequested();
// do more work
ct.ThrowIfCancellationRequested();
// repeat until done.
}
明らかに、協調的なキャンセルを使用するこのアプローチでは、メソッド内の作業をどれだけ小さく分割できるかに依存するため、メソッドはタイムアウトで正確にタイムアウトしません。
別のスレッドの使用を回避したい場合 ( のためにCancellationTokenSource
)、開始時間を追跡し、メソッドのさまざまなポイントで (タイムアウトを超えたかどうかを確認するために) 経過時間を確認できます (どのようにct.ThrowIfCancellationRequested()
上で使用されます。