操作を手動でキャンセルできる一方で、一定時間後に非同期操作をキャンセルするには、次のようなものを使用します
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
cts.CancelAfter(5000);
これにより、5 秒後にキャンセルされます。自分で操作をキャンセルするには、token
を async メソッドに渡し、メソッドを使用するtoken.ThrowifCancellationRequested()
だけです。ここで、イベント ハンドラーをどこかに発火するように設定しますcts.Cancel()
。
したがって、完全な例は次のとおりです。
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
cts.CancelAfter(5000);
// Set up the event handler on some button.
if (cancelSource != null)
{
cancelHandler = delegate
{
Cancel(cts);
};
stopButton.Click -= cancelHandler;
stopButton.Click += cancelHandler;
}
// Now launch the method.
SomeMethodAsync(token);
stopButton
実行中のタスクをキャンセルするためにクリックするボタンはどこにありますか
private void Cancel(CancellationTokenSource cts)
{
cts.Cancel();
}
メソッドは次のように定義されます。
SomeMethodAsync(CancellationToken token)
{
Task t = Task.Factory.StartNew(() =>
{
msTimeout = 5000;
Pump(token);
}, token,
TaskCreationOptions.None,
TaskScheduler.Default);
}
ここで、スレッドを操作できるようにするだけでなく、ユーザーによるキャンセルも可能にするには、「ポンピング」メソッドを記述する必要があります。
int msTimeout;
bool timeLimitReached = false;
private void Pump(CancellationToken token)
{
DateTime now = DateTime.Now;
System.Timer t = new System.Timer(100);
t.Elapsed -= t_Elapsed;
t.Elapsed += t_Elapsed;
t.Start();
while(!timeLimitReached)
{
Thread.Sleep(250);
token.ThrowIfCancellationRequested();
}
}
void t_Elapsed(object sender, ElapsedEventArgs e)
{
TimeSpan elapsed = DateTime.Now - this.readyUpInitialised;
if (elapsed > msTimeout)
{
timeLimitReached = true;
t.Stop();
t.Dispose();
}
}
注、SomeAsyncMethod
呼び出し元にすぐに戻ります。Task
発信者もブロックするには、呼び出し階層を上に移動する必要があります。