【问题标题】:How to stop async task and start it again upon user cancellation [closed]如何在用户取消后停止异步任务并重新启动它[关闭]
【发布时间】:2014-03-23 19:08:46
【问题描述】:

我需要异步实现一个长时间运行的进程。 我已经使用 Task.Run() 完成了所有工作,没有任何问题。 然而,需求发生了变化,现在他们想要任何正在进行的异步任务的“取消”功能。 如果我以更简单的形式解释要求; 我有一个按钮、文本框和一个列表框。 当用户在文本框中输入内容并单击按钮时,它应该从 db 获取数据并使用 db 结果填充列表框(假设这是一个长时间运行的过程) 如果用户改变主意并在文本框中再次输入内容并单击按钮,它应该停止当前正在运行的任务,清除列表框并应该使用在他的输入中输入的新值启动任务(获取和显示数据)第二次尝试。

我尝试为此使用取消令牌,但没有成功。 如果有人可以帮助我,我将不胜感激。

【问题讨论】:

  • 取消令牌有什么问题?
  • 请发布您的代码。如果你让每个人都猜测你做错了什么,你将不会得到任何有用的答案。
  • 又一个“我试过这个但没用”的问题...伙计,这种趋势让我想放弃写答案。 发布特定的错误消息和与问题直接相关的代码有多难?我们无法读懂您的想法,也无法看到您的屏幕。请更彻底。

标签: c# .net task-parallel-library cancellationtokensource


【解决方案1】:

使用 CancellationToken 不会神奇地取消正在运行的任务。任务内部运行的代码需要知道令牌并主动检查它是否取消。框架提供给您的所有方法都已经这样做了,因此您可能不习惯这样做。但是,听起来您已经编写了自己的方法,该方法在这些行旁边接受 CancellationToken

public Task Method(CancellationToken ct)
{
 // do some database work here
}

在这种情况下,您应该查看用于与数据库通信的库,看看它是否支持 CancellationToken。如果是,则将其传递给图书馆。如果没有,那么您可以像这样在数据库操作完成后手动检查令牌

public Task<int> Method(CancellationToken ct)
{
 // do some database work here
 ct.ThrowIfCancelled();
 // return DB result here
}

使用这种方法,您不会取消数据库请求,但至少不会返回结果,并且调用请求的代码将能够处理取消。

如果您碰巧使用了 EntityFramework 之类的库,那么您将能够为某些请求提供 CancellationToken,从而有可能避免数据库浪费工作以及能够立即取消任务。

【讨论】:

  • 很好,我正在寻找这样的东西。谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 2018-02-22
  • 2019-06-03
  • 1970-01-01
相关资源
最近更新 更多