等待一个任务列表而不阻塞另一个任务列表
Await a task list without blocking another task list
我正在编写一段代码,从一个来源获取数据,进行一些处理,然后将其保存到另一个来源。由于两端的延迟很高,我正在尝试使用 async/await 来等待加载和保存操作完成。理想情况下,这将启动所有输入任务,并且当每个输入任务完成时,它会进行一些快速处理,然后启动输出任务 - 使用 Task.WaitAll 会导致程序在新任务开始时什么都不做。
由于第二个异步任务依赖于第一个异步任务的结果,所以我不知道如何处理第二个等待,让它恢复处理第一个等待的其他结果——一旦结果是处理并命中第二个 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 */
}
不要等待单一方法,而是使用延续创建 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);
这将以异步方式处理您的所有任务。
如果我理解正确的话,你可以试试这个:
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
不需要 return 任务,但这取决于它在做什么。
我正在编写一段代码,从一个来源获取数据,进行一些处理,然后将其保存到另一个来源。由于两端的延迟很高,我正在尝试使用 async/await 来等待加载和保存操作完成。理想情况下,这将启动所有输入任务,并且当每个输入任务完成时,它会进行一些快速处理,然后启动输出任务 - 使用 Task.WaitAll 会导致程序在新任务开始时什么都不做。
由于第二个异步任务依赖于第一个异步任务的结果,所以我不知道如何处理第二个等待,让它恢复处理第一个等待的其他结果——一旦结果是处理并命中第二个 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 */
}
不要等待单一方法,而是使用延续创建 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);
这将以异步方式处理您的所有任务。
如果我理解正确的话,你可以试试这个:
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
不需要 return 任务,但这取决于它在做什么。