触发多个异步任务并仅更新最新任务的结果
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. 🙂