【发布时间】:2015-08-05 11:04:38
【问题描述】:
我有一个搜索方法可以将搜索建议返回到 UI。每次用户在搜索框中输入新字符时都会触发此方法。
我添加了一些取消代码来取消之前的搜索请求。这有效,但并非一直有效。
private CancellationTokenSource cancellationTokenSource;
private async Task UserSearch(string searchCriteria)
{
Debug.WriteLine("Searching for {0}....", searchCriteria);
try
{
var cts = new CancellationTokenSource();
this.Suggestions = await this.SearchAsync(searchCriteria, cts.Token);
}
catch (OperationCanceledException)
{
Debug.WriteLine("Search({0}) cancelled", searchCriteria);
}
}
private async Task<IList<string>> SearchAsync(string searchCriteria, CancellationToken cancelToken)
{
CancellationTokenSource previousCts = this.cancellationTokenSource;
CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancelToken);
this.cancellationTokenSource = linkedCts;
// if previous task running cancel it
if (previousCts != null)
{
previousCts.Cancel();
}
linkedCts.Token.ThrowIfCancellationRequested();
List<string> results =
(await this.searchProvider.SearchAsync(searchCriteria, linkedCts.Token)).ToList();
Debug.WriteLine("Search({0}) returned {1} records", searchCriteria, results.Count);
linkedCts.Dispose();
this.cancellationTokenSource = null;
return results;
}
例如。我收到以下调试消息:
SearchTerm changing to: Di
Searching for Di....
SearchTerm changing to: Dia
Searching for Dia....
Search(Di) cancelled
SearchTerm changing to: Diap
Searching for Diap....
Search(Diap) returned 323 records
Search(Dia) returned 3230 records
如您所见,第一次搜索被取消,但第二次没有,并且在最后一次搜索后返回,给用户提供了不正确的结果。
如何确保以前的任务总是被取消?
【问题讨论】:
-
SearchAsync 有什么作用?它真的会响应取消吗?
-
@usr 它本质上是传递给 SQLite.Net
QueryAsync方法 github.com/oysteinkrog/SQLite.Net-PCL/blob/master/src/… -
如果您在取消之前已经执行了查询,并且调用的最低 API 在查询时没有监听该令牌,那么您将不会被取消。
-
感谢@YuvalItzchakov 在
this.SearchProvider.SearchAsync()方法的底部添加一个额外的token.ThowIfCancellationRequested()似乎可以解决问题。是否有关于多久添加一次此检查的规则?
标签: c# .net asynchronous async-await task-parallel-library