![](/img/trans.png)
[英]Cancel Async Task with CancellationTokenSource from a button click not working
[英]Canceling the previous Async Task using CancellationTokenSource
我需要实现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 stocks方法,在这种情况下,我想取消以前用字母“ A”调用的GetStocks
任务。
.Net中异步编程的最佳实践之一是Async all way 。 看起来您的方法不是基于异步的,也不接受CancellationToken
。 您需要将其添加到您的方法中, Task.Run
只有Task.Run
会尝试取消您的任务,但效果不佳。
另外,仅创建CancellationTokenSource
是不够的-您需要在代码中使用它的.Token
属性-这恰好是该令牌:
await Task.Run(() => { CreateStockingCollection(); }, cts.Token);
取消是协作的,因此您需要将其传递给自己的代码并使它响应该令牌:
public async Task GetStocks()
{
var stockings = new List<Services.Models.Admin.SiteStockingLevelsModel>();
IsBusy = true;
cts?.Cancel();
cts = new CancellationTokenSource();
var token = cts.Token;
await Task.Run(() => { CreateStockingCollection(token); });
ValidateMaterials();
IsBusy = false;
}
private void CreateStockingCollection(CancellationToken token)
{
var stockings = _siteStockingLevelsService.GetSiteInventoryLevels(SiteId, token);
CreateStockingLevelCompareCollection(stockings);
StockingLevels =
_mapper.Map<TrulyObservableCollection<SiteStockingLevelsModel>>(stockings);
((INotifyPropertyChanged)StockingLevels).PropertyChanged +=
(x, y) => CompareStockingChanges();
CompareStockingChanges();
}
在这里,我将其传递给GetSiteInventoryLevels
,这听起来像是这项工作的长期工作。 现在, GetSiteInventoryLevels
必须获取CancellationToken
并将其传递给正在使用的任何API。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.