【问题标题】:Cancel async and await method in C#在 C# 中取消 async 和 await 方法
【发布时间】:2017-06-03 20:32:40
【问题描述】:

我在 C# 中有一个异步调用,我正在尝试实现取消逻辑。我在 Internet 上进行了搜索,但找不到解决问题的方法。

我有一个带有开始按钮、取消按钮和显示结果的文本框的 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 调用这个方法,但没有任何帮助。有人可以告诉我如何以正确的方式实现这个取消逻辑吗? 提前致谢!

【问题讨论】:

  • 你试过for里面的那段代码了吗?

标签: c# winforms asynchronous async-await cancellation


【解决方案1】:

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

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

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

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

【讨论】:

  • 这就是解决方案。非常感谢!我可以以某种方式处理上面代码中的异常吗?
  • 抱歉,我不太明白你想用这个异常做什么。
  • 没关系。我明白了:)谢谢你的帮助!我将带有 await 语句的代码放在 try - catch 块中,并将 TaskCancelledException 转换为 MessageBox,并立即使用 return 语句跳出代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多