Jac*_*rts 16 .net c# lambda task-parallel-library async-await
我正在尝试使用Task.WaitAll
任务列表.事情是任务是异步lambda,Tasks.WaitAll
因为它永远不会等待.
这是一个示例代码块:
List<Task> tasks = new List<Task>();
tasks.Add(Task.Factory.StartNew(async () =>
{
using (dbContext = new DatabaseContext())
{
var records = await dbContext.Where(r => r.Id = 100).ToListAsync();
//do long cpu process here...
}
}
Task.WaitAll(tasks);
//do more stuff here
Run Code Online (Sandbox Code Playgroud)
这不会因为异步lambda而等待.那我该如何等待我的lambda中的I/O操作呢?
Cha*_*ger 19
Task.Factory.StartNew
不识别async
委托,因为没有重载接受返回a的函数Task
.
这加上其他原因(参见StartNew是危险的)是你应该在Task.Run
这里使用的原因:
tasks.Add(Task.Run(async () => ...
Run Code Online (Sandbox Code Playgroud)
Yuv*_*kov 19
这不会因为异步lambda而等待.那我该如何等待我的lambda中的I/O操作呢?
之所以Task.WaitAll
不等待async lambda提供的IO工作的完成是因为Task.Factory.StartNew
实际返回了一个Task<Task>
.由于您的列表是List<Task>
(并且Task<T>
派生自Task
),因此您等待启动的外部任务StartNew
,同时忽略由异步lambda创建的内部任务.这就是为什么他们说对于异步Task.Factory.StartNew
是危险的.
你怎么能解决这个问题?您可以显式调用Task<Task>.Unwrap()
以获取内部任务:
List<Task> tasks = new List<Task>();
tasks.Add(Task.Factory.StartNew(async () =>
{
using (dbContext = new DatabaseContext())
{
var records = await dbContext.Where(r => r.Id = 100).ToListAsync();
//do long cpu process here...
}
}).Unwrap());
Run Code Online (Sandbox Code Playgroud)
或者像其他人说的那样,你可以打电话Task.Run
:
tasks.Add(Task.Run(async () => /* lambda */);
Run Code Online (Sandbox Code Playgroud)
此外,既然你想做正确的事情,你会想要使用Task.WhenAll
,为什么是异步等待,而不是Task.WaitAll
同步阻止:
await Task.WhenAll(tasks);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13587 次 |
最近记录: |