我需要实施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方法,在这种情况下,我想取消之前调用的GetStocks
任务用字母“A”。
答案 0 :(得分:1)
.Net中异步编程的最佳实践之一是Async all the way。看起来您的方法不是基于异步的,也不接受CancellationToken
。您需要将其添加到您的方法中,否则只有Task.Run
会尝试取消您的任务,这将无法正常工作。
此外,仅CancellationTokenSource
的唯一创建是不够的 - 您需要在代码中使用它的.Token
属性 - 这正是该令牌:
await Task.Run(() => { CreateStockingCollection(); }, cts.Token);
答案 1 :(得分:1)
取消是合作的,因此您需要将其传递给您自己的代码并让它响应该令牌:
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。