【发布时间】:2017-07-29 09:49:16
【问题描述】:
我需要实现async 任务取消。我知道CancellationTokenSource 会帮助我实现这一目标。但是我找不到合适的方法。
我有一个搜索文本框,每当用户在文本框中键入时,对于每个 textchanged 事件,我都会调用GetStocks 方法,如下所示,
public async Task GetStocks()
{
var stockings = new List<Services.Models.Admin.SiteStockingLevelsModel>();
IsBusy = true;
cts?.Cancel();
cts = new CancellationTokenSource();
await Task.Run(() => { CreateStockingCollection(); });
ValidateMaterials();
IsBusy = false;
}
CreateStockingCollection方法如下图,
private void CreateStockingCollection()
{
var stockings = _siteStockingLevelsService.GetSiteInventoryLevels(SiteId);
CreateStockingLevelCompareCollection(stockings);
StockingLevels =
_mapper.Map<TrulyObservableCollection<SiteStockingLevelsModel>>(stockings);
((INotifyPropertyChanged)StockingLevels).PropertyChanged +=
(x, y) => CompareStockingChanges();
CompareStockingChanges();
}
我的要求是,
示例假设用户想要输入“Abc”。当用户键入“A”时,GetStocks 方法将被调用,用户立即输入“b”,将再次调用 get stock 方法,在这种情况下,我想取消之前用字母“A”调用的 GetStocks 任务”。
【问题讨论】:
-
仅供参考:更适合这种情况的可能是“反应式扩展”。基于文本更改事件创建任务可以通过例如仅在至少有 2 个字符并且搜索文本在 200 毫秒内没有更改时才开始搜索而得到显着改进。这将减少昂贵的通话。可以在此处找到示例:stackoverflow.com/questions/22873541/….
-
@PeterBons 有一个很好的观点,但除此之外,您没有在发布的代码中的任何地方使用令牌。您需要将 CTS 的令牌传递给任何应该参与合作取消的任务。然后任务应该检查令牌是否表示应该取消操作。对于非 CPU 绑定操作,这实际上是不可能的,除非令牌可以一直向下传递(通常通过使所有调用异步并支持取消令牌)。例如,这样您就可以取消长时间运行的数据库查询。
-
这是一个 WPF 应用程序。
-
您能否提供此场景的任何实现示例。
-
你想通过打字来实现什么似乎对用户不友好,想想用户打字的速度有多快,对我来说,当有人输入来自整个单词并开始一个具有当前字符串的新单词。看起来您只想更改发送到任务但不应生成新任务的输入字符串。通常,当用户通过按下按钮取消长时间运行的任务时使用取消令牌源,这会停止也在更新进度条的任务。
标签: c# multithreading asynchronous task task-parallel-library