在C#中取消async和await方法

时间:2017-01-19 08:08:37

标签: c# winforms asynchronous async-await cancellation

我在C#中进行异步调用,并尝试实现取消逻辑。我在互联网上搜索,但我无法找到解决问题的方法。

我有一个带有“开始”按钮的Windows窗体,“取消”按钮和一个显示结果的文本框。以下代码:

private CancellationTokenSource _cancelSource;
private CancellationToken _token;

private void btnStart_Click(object sender, EventArgs e)
{
  DisplayPrimeCountsAsync(_token);
}

private async void DisplayPrimeCountsAsync(CancellationToken token)
{
   btnStart.Enabled = false;

   for (int i = 0; i < 100; i++)
   {
     textBox1.Text += await GetPrimesCountAsync(i*1000000 + 2, 1000000, token) + Environment.NewLine;
   }

    btnStart.Enabled = true;
 }

 private Task<int> GetPrimesCountAsync(int start, int count, CancellationToken token)
 {
    return
       Task.Run(() =>
           ParallelEnumerable.Range(start, count).Count(n =>
              Enumerable.Range(2, (int) Math.Sqrt(n) - 1).All(i => n%i > 0)), token);
  }

private void btnCancel_Click(object sender, EventArgs e)
{
  _cancelSource = new CancellationTokenSource();
  _token = _cancelSource.Token;
  _cancelSource.Cancel();
  btnCancel.Enabled = false;
 }

现在这根本没有取消。我找到了以下代码:

 if (token.IsCancellationRequested) 
 {
   token.ThrowIfCancellationRequested();
 }

但是我不知道把它放在哪里。试着将这个和素数linq表达式放到另一个方法中并在Task.Run上调用这个方法但没有任何帮助。有人能告诉我如何以正确的方式实现这种取消逻辑吗? 提前谢谢!

1 个答案:

答案 0 :(得分:2)

在启动任务之前,您是否尝试调用以下代码?

_cancelSource = new CancellationTokenSource();
_token = _cancelSource.Token;

感觉就像你启动任务时令牌为空,然后你设置它。 (虽然没试过)

当然,在这种情况下,您必须从取消方法中删除相同的代码。