c# - 取消自动完成字段的任务不会取消所有以前的任务

标签 c# .net asynchronous async-await task-parallel-library

我有一个搜索方法可以将搜索建议返回到 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

如您所见,第一个搜索被取消,但第二个搜索没有,它在最后一个搜索后返回给用户错误的结果。

如何确保以前的任务总是被取消?

最佳答案

我认为您的解决方案可能有点复杂。您需要做的就是查看是否有正在进行的操作尚未取消并将其取消。然后执行新的搜索。未经测试,但我认为应该这样做。

private CancellationTokenSource cancellationTokenSource;

private async Task UserSearch(string searchCriteria)
{
    Debug.WriteLine("Searching for {0}....", searchCriteria);

    try
    {       
        if(cancellationTokenSource != null && 
           !cancellationTokenSource.IsCancellationRequested)
        {
            cancellationTokenSource.Cancel();
        }

        cancellationTokenSource = new CancellationTokenSource();

        this.Suggestions = await this.searchProvider.SearchAsync(searchCriteria, linkedCts.Token);

        Debug.WriteLine("Search({0}) returned {1} records", searchCriteria, results.Count);

    }
    catch (OperationCanceledException)
    {
        Debug.WriteLine("Search({0}) cancelled", searchCriteria);
    }
}

关于c# - 取消自动完成字段的任务不会取消所有以前的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31830713/

相关文章:

c# - Awesomium - 返回对象名称

c# - 测量一个函数所用的时间,不明白为什么时差是负的

c# - 序列化UTC时间c#

c# - Task.WaitAll 不等待子任务?

Javascript 同步 AJAX 超时

c# - 什么是终结者?

c# - .NET WinForms 多线程行为 : Setting property value in ThreadPool. QueueUserWorkItem 尽管有异常

.net - F# 处理值和引用

java - 将多个 ReactiveX 流合并为一个结果流

c++ - 非阻塞 io_service::run