【发布时间】:2018-11-27 09:59:27
【问题描述】:
我正在阅读 this post 关于 Parallel.ForEach 的内容,其中指出“Parallel.ForEach 与传入异步方法不兼容。”
所以,为了检查我写了这段代码:
static async Task Main(string[] args)
{
var results = new ConcurrentDictionary<string, int>();
Parallel.ForEach(Enumerable.Range(0, 100), async index =>
{
var res = await DoAsyncJob(index);
results.TryAdd(index.ToString(), res);
});
Console.ReadLine();
}
static async Task<int> DoAsyncJob(int i)
{
Thread.Sleep(100);
return await Task.FromResult(i * 10);
}
此代码同时填写results 字典。
顺便说一句,我创建了一个ConcurrentDictionary<string, int> 类型的字典,因为如果我有ConcurrentDictionary<int, int>,当我在调试模式下探索它的元素时,我看到元素是按键排序的,我认为因此添加了元素。
所以,我想知道我的代码是否有效?如果它“与传入异步方法不兼容”,为什么它运行良好?
【问题讨论】:
-
不要。
Parallel.ForEach用于 CPU 密集型计算,不识别异步方法。它不会等待它们,本质上是将它们转换为async void即发即弃的呼叫。无论如何,您的方法不是异步的,因此无法说出 正确的 调用是什么样的 -
@PanagiotisKanavos 请发布您的信息来源。谢谢
-
I want to know is my code is valid?No.why it works well?它没有,但你没有意识到它,因为 a) 它不执行任何异步工作。 -
Parallel.ForEach- “安排多个线程并行执行以下工作” -async- “好吧,这个线程没有什么有用的工作做,直到其他事情完成这个等待”。即使它确实有效(它没有,正如 Panagitotis 所说,它完全是同步的),你以一种奇怪的方式组合事物,过度分配资源然后忽略它们。 -
@Seabizkit 没有什么可说服的。没有接受任务的重载。没有它,就无法
await任何异步调用。async不会等待任何东西,也不会让任何东西异步运行。async void调用无法等待,这就是为什么它们被视为事件处理程序之外的错误。
标签: c# async-await parallel.foreach