触发多个异步任务并仅更新最新任务的结果

c#

我一直在修补 Blazor 并遇到了 async/await 问题。我添加了一个搜索输入字段,它触发一个异步操作,当用户开始输入时,该操作将搜索结果返回给用户。问题是异步任务以错误的顺序完成。触发的第一个任务返回并使已完成的后续任务的结果无效。

我提出了一个涉及跟踪任务的解决方案,但这是正确的做法还是我的做法错误?

我目前的解决方案是这样的:

        private List<Task> runningTasks = new List<Task>();

        protected async Task OnSearchTermChanged(ChangeEventArgs e)
        {
            SearchTerm = e.Value.ToString();

            if(SearchTerm.Length >= 3)
            {
                SearchResult = null;
                var task = AdService.SearchUsers(SearchTerm);
                runningTasks.Add(task);
                var result = await task;

                if(task == runningTasks.Last())
                {
                    SearchResult = result;
                }
            }
            else
            {
                SearchResult ??= new List<AdUser>();
                SearchResult.Clear();
            }
        }

回答

对于这种场景,我使用我所谓的“异步上下文”(可能是一个非常糟糕的名字,因为如今“上下文”可能意味着很多东西)。您只需要某种唯一值(new object()就足够了),将此值捕获到 之前的局部变量中await,然后在 之后进行比较await。如果它们不匹配,那么该代码就知道它不再是当前的。

private object _context;

protected async Task OnSearchTermChanged(ChangeEventArgs e)
{
  SearchTerm = e.Value.ToString();

  if (SearchTerm.Length >= 3)
  {
    var localContext = _context = new object();
    SearchResult = null;
    var task = AdService.SearchUsers(SearchTerm);
    var result = await task;

    if (localContext == _context)
    {
      SearchResult = result;
    }
  }
  else
  {
    _context = null;
  }
}

  • Instead of `context` you could also call it `ticket`. Or `ticketToRide` for more style points. 🙂

以上是触发多个异步任务并仅更新最新任务的结果的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>