我正在尝试取消使用 await 调用的DoSomethingAsync方法的执行。
当我点击取消按钮时,执行没有取消,我没有看到“执行被取消”消息框,而是我看到另一个消息框。
我不明白为什么它不起作用。我还在学习C#的这一部分,我在http://www.codeproject.com/Articles/127291/C-vNext-New-Asynchronous-Pattern#heading0015(我简化了它)中采用了这个例子。
public class MyClass : Class
{
CancellationTokenSource cts;
private async void searchButton_Click(object sender, EventArgs e)
{
await DoSomethingAsync();
}
private void cancelButton_Click(object sender, EventArgs e)
{
cts.Cancel();
}
async void DoSomethingAsync()
{
cts = new CancellationTokenSource();
try
{
await SuperSlowProcess();
MessageBox.Show("You will only see this if execution is not cancelled");
}
catch (TaskCanceledException)
{
MessageBox.Show("Execution was cancelled");
}
}
}
答案 0 :(得分:1)
为了使其有效,您实际上需要在CancellationToken
中使用SuperSlowProcess
:
public Task SuperSlowProcess(CancellationToken cancellationToken)
{
return Task.Run(() => {
// you need to check cancellationToken periodically to check if cancellation has been requested
for (int i = 0; i < 10; i++)
{
cancellationToken.ThrowIfCancellationRequested(); // this will throw OperationCancelledException after CancellationTokenSource.Cancel() is called
Thread.Sleep(200); // to emulate super slow process
}
});
}
当然,这取决于SuperSlowProcess
的实施。如果无法定期检查CancellationToken
,您只能检查一次 - 最后,就像这样:
public async Task SuperSlowProcess2(CancellationToken cancellationToken)
{
var response = await CallExternalApi();
cancellationToken.ThrowIfCancellationRequested();
}
然后
async void DoSomethingAsync()
{
cts = new CancellationTokenSource();
try
{
await SuperSlowProcess(cts.Token);
MessageBox.Show("You will only see this if execution is not cancelled");
}
catch (OperationCanceledException) // Note that exception type is different
{
MessageBox.Show("Execution was cancelled");
}
}