要在一定时间后取消异步操作,同时仍然能够手动取消操作,请使用以下内容
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
cts.CancelAfter(5000);
这将导致五秒钟后取消。要取消您自己的操作,您只需将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
在呼叫层次结构中向上移动。