我在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上调用这个方法但没有任何帮助。有人能告诉我如何以正确的方式实现这种取消逻辑吗? 提前谢谢!
答案 0 :(得分:2)
在启动任务之前,您是否尝试调用以下代码?
_cancelSource = new CancellationTokenSource();
_token = _cancelSource.Token;
感觉就像你启动任务时令牌为空,然后你设置它。 (虽然没试过)
当然,在这种情况下,您必须从取消方法中删除相同的代码。