我正在处理一段代码,该代码从一个源获取数据,进行一些处理,然后将其保存到不同的源。由于两端的延迟都很高,我试图使用async / await来等待加载和保存操作完成。理想情况下,这将启动所有输入任务,当每个任务完成时,它会执行一些快速处理,然后启动输出任务 - 使用Task.WaitAll会导致程序在新任务可能启动时无效。
由于第二个异步任务取决于第一个异步任务的结果,我无法弄清楚如何处理第二个异步等待,以便让它从第一个await恢复处理其他结果 - 一旦结果是处理完第二次await后,它会完全阻塞,直到完成保存功能,而不是恢复处理其他结果。我尝试这样的事情,我做错了什么?
async Task MainAsync()
{
/* gets a list of id's */
var dataRequests = ids.Select(id => LoadEntryById(id)).ToList();
foreach(var request in dataRequests)
{
RawEntry response = await request;
ProcessedEntry result = doSomething(response);
await SaveResult(result);
}
}
async Task<RawEntry> LoadEntryById(int id)
{
/* IO task */
}
async Task SaveResult(ProcessedEntry result)
{
/* IO task */
}
答案 0 :(得分:3)
不是等待单一方法,而是使用续集创建List<Task>
,然后使用Task.WhenAll
:
var tasks = ids.Select(async id => {
var response = await LoadEntryById(id);
var result = doSomething(response);
await SaveResult(result);
}).ToList();
await Task.WhenAll(tasks);
这将以异步方式处理您的所有任务。
答案 1 :(得分:-1)
如果我理解正确,你可以试试这个:
Parallel.Foreach( ids.Select(id => LoadEntryById(id)), (rawEntry) => {
var result = doSomething(rawEntry);
await SaveResult(result);
}
RawEntry LoadEntryById(int id)
{
/* IO task */
}
async Task SaveResult(ProcessedEntry result)
{
/* IO task */
}
在此设置中LoadEntryById
不需要返回任务,但这取决于它正在做什么。