c# - 在异步无效中取消任务

标签 c# task cancellation cancellationtokensource

嗨,我有一个列表框 每当用户选择一个项目时,就会向网络发送一个请求 现在我想在用户选择该项目时取消之前的操作,然后开始新的操作。

我使用以下代码来做到这一点,我想知道这些代码是否工作正常。或者我应该尝试其他方式?

private CancellationTokenSource ts = new CancellationTokenSource();
private async void Subf2mCore(CancellationToken ct)
{
  HtmlDocument doc = await web.LoadFromWebAsync(url);
   ...
  foreach (var node in doc)
  {
    if (!ct.IsCancellationRequested)
    {
      ....
    }
  }
}

我以这种方式运行 func
ts?.Cancel();
ts = new CancellationTokenSource();
Subf2mCore(ts.Token);

最佳答案

从技术上讲,您可以这样说,但是请注意:您开火了就忘记了,让我们返回 Task让来电者知道 Subf2mCore已完成、失败或取消:

private async Task Subf2mCore(CancellationToken ct)
{
  HtmlDocument doc = await web.LoadFromWebAsync(url);
   ...
  foreach (var node in doc)
  {
    // Often we cancel by throwing exception: 
    // it's easy to detect that the task is cancelled by catching this exception
    // ct.ThrowIfCancellationRequested();

    // You prefer to cancel manually: 
    // your cancellation can be silent (no exceptions) but it'll be 
    // difficult for caller to detect if task completed or not 
    // (partially completed and cancelled)
    if (!ct.IsCancellationRequested)
    {
      ....
    }
  }
}

// If we don't want to cancel 
private async Task Subf2mCore() => Subf2mCore(CancellationToken.None);

用法:别忘了Dispose CancellationTokenSource实例:
using (CancellationTokenSource ts = new CancellationTokenSource()) {
  ...
  await Subf2mCore(ts.Token);
  ...
}

编辑:如果您想从外面取消:
private CancellationTokenSource ts = null;

...

using (CancellationTokenSource _ts = new CancellationTokenSource()) {
  // previous task (if any) cancellation
  if (null != ts)
    ts.Cancel();

  // let cancel from outside
  ts = _ts;

  try {
    ...
    await Subf2mCore(_ts.Token);
    ...
  }
  finally {
    // task completed, we can't cancel it any more
    ts = null;
  }
}

关于c# - 在异步无效中取消任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59484384/

相关文章:

c# - 资源争用

c# 在 for 循环中创建对象的新实例

vba - 停止带有取消请求的代码时如何删除运行时错误 '3464'

c# - 任务取消暂停 UI

javascript - 取消链接中 onClick 触发的 javascript 函数

C#/Linq 获取相邻的集合

c# - 型号为空?

mysql - 选择用于创建任务管理 Web 应用程序的语言

java - Gradle 任务替换 .java 文件中的字符串

c# - 为什么 TaskCompleted 在操作结束之前执行