简体   繁体   English

取消C#中的异步和等待方法

[英]Cancel async and await method in C#

I have an asynchronous call in C# and I'm trying to implement a cancellation logic. 我在C#中有一个异步调用,并且正在尝试实现取消逻辑。 I searched around the Internet but I couldn't find a solution for my issue. 我在Internet上搜索,但找不到解决我问题的方法。

I have a Windows Forms with a Start button, a Cancel button and a textbox to show the results. 我有一个带有“开始”按钮,“取消”按钮和文本框的Windows窗体,以显示结果。 Following code: 以下代码:

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;
 }

Now this is not getting cancelled at all. 现在,这根本没有被取消。 I have found following piece of code: 我发现以下代码:

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

but I don't know where to put this in. Tried to put this and the prime numbers linq expression into another method and call this method over Task.Run but nothing helps. 但是我不知道将其放在哪里。试图将其和质数linq表达式放入另一个方法,并通过Task.Run调用此方法,但没有任何帮助。 Can someone show me how to implement this cancellation logic the right way? 有人可以告诉我如何以正确的方式实现此取消逻辑吗? Thanks in advance! 提前致谢!

Did you try to call the following code before launching your task? 您是否在启动任务之前尝试调用以下代码?

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

Feels like when you launch your task the token is null and you set it afterward. 就像您启动任务时那样,令牌为空,然后再进行设置。 (didn't try it though) (虽然没有尝试)

Of course in this case you have to remove the same code from your cancel method. 当然,在这种情况下,您必须从cancel方法中删除相同的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM