取消执行使用await调用的方法

时间:2016-03-22 19:00:27

标签: c# async-await

我正在尝试取消使用 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");
    }
  }
}

1 个答案:

答案 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");
    }
}