使用foreach/WhenAll时实际发生了什么?

And*_*kin 2 .net task-parallel-library

从线程的角度来看,这段代码会发生什么?

public static Task ForEach<T>(IEnumerable<T> items, Func<T, Task> process) {
    var tasks = new List<Task>();
    foreach (var item in items) {
        tasks.Add(process(item));
    }
    return Task.WhenAll(tasks);
}
Run Code Online (Sandbox Code Playgroud)

是否所有任务都是并行运行的,还是可以按顺序执行?
如果集合很大,是否会出现问题(除内存使用外)?

Tho*_*que 5

是否所有任务都是并行运行的,还是可以按顺序执行?
如果集合很大,是否会出现问题(除内存使用外)?

一般来说,没有办法回答这个问题,因为它取决于Task返回的类型process.A Task不是线程 ; 它只是表示操作完成时通知机制的操作.某些任务是使用线程实现的(例如,当您使用Task.Run或时Task.Factory.StartNew),但其他任务不是(例如,创建的任务TaskCompletionSource<T>).

现在,假设在您的情况下,process返回在线程中运行的任务.同样,这取决于任务的安排方式.通常,如果您使用Task.RunTask.Factory.StartNew使用默认创建选项,它将使用来自的线程ThreadPool.因此,如果您创建的任务数超过池中最大线程数,则它们将排队,直到线程可用.

因此,几个任务将并行运行,但不是全部; 它取决于最大线程数ThreadPool.