我想并行执行许多长时间运行的 CPU 和 IO 密集进程(如
Thread.Sleep()
所示)。这就是我使用 Parallel.ForΕach
循环的原因。在一段时间内不需要这些结果。这就是为什么我想继续不同的工作并将此任务任务(可以这么说)“挂起”到不同的线程,而每个Parallel.ForΕach
在不同的线程上再次执行。这就是为什么我返回封装在 Parallel.ForΕach
语句中的 Task.Run()
。代码如下:
internal class Program
{
static async Task Main(string[] args)
{
Console.WriteLine($"Before ParallelForeach on thread: {Environment.CurrentManagedThreadId}"); //Main debug 1
await TaskContainingParallelForeach();
Console.WriteLine($"After ParallelForeach on thread: {Environment.CurrentManagedThreadId}"); //Main debug 2
int counter = 0;
while (counter < 7)
{
Console.WriteLine($"{counter}. one second gone on thread: {Environment.CurrentManagedThreadId} at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
Thread.Sleep(1000);
counter++;
}
Console.ReadKey();
}
public static Task TaskContainingParallelForeach()
{
return Task.Run(() =>
{
Console.WriteLine($"Inside ParallelForeach on thread: {Environment.CurrentManagedThreadId}");
int[] numbers = { 1, 3, 2 };
Parallel.ForEach(numbers, (num) =>
{
Console.WriteLine($"{num} is running on thread: {Environment.CurrentManagedThreadId}");
Thread.Sleep(num * 1000);
Console.WriteLine($"{num} stopped on thread: {Environment.CurrentManagedThreadId} at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
});
});
}}
这给了我以下输出:
Console Output without await:
Before TaskContainingParallelForeach on thread: 1
Inside TaskContainingParallelForeach on thread: 3 // why is -below- first done all the work from the ParallelForeach?
1 is running on thread: 3
3 is running on thread: 4
2 is running on thread: 6
1 stopped on thread: 3 at 1734365740995
2 stopped on thread: 6 at 1734365741996
3 stopped on thread: 4 at 1734365742996
After TaskContainingParallelForeach on thread: 3 // why is it the thread with id 3 here - expected was 1
0. one second gone on thread: 3 at 1734365742996
1. one second gone on thread: 3 at 1734365743997
2. one second gone on thread: 3 at 1734365745008
3. one second gone on thread: 3 at 1734365746023
4. one second gone on thread: 3 at 1734365747035
5. one second gone on thread: 3 at 1734365748047
6. one second gone on thread: 3 at 1734365749061
Parallel.ForEach
才会运行,并且仅在其完成后 - while 循环才开始。 await
运算符的行为应类似于: (原始文档)await 运算符暂停对封闭异步方法的评估,直到异步操作。我的异步方法是 TaskContainingParallelForeach。还是不是?
为什么
After TaskContainingParallelForeach on thread
的线程ID是3而不是1?为什么 while 循环没有在线程 1 上执行?
但是,从 await
中删除 await TaskContainingParallelForeach();
运算符可以获得所需的结果:
Console output without await:
Before TaskContainingParallelForeach on thread: 1
After TaskContainingParallelForeach on thread: 1
Inside TaskContainingParallelForeach on thread: 3
1 is running on thread: 3
3 is running on thread: 4
2 is running on thread: 5
0. one second gone on thread: 1 at 1734364096009
1 stopped on thread: 3 at 1734364097021
1. one second gone on thread: 1 at 1734364097036
2 stopped on thread: 5 at 1734364098027
2. one second gone on thread: 1 at 1734364098043
3 stopped on thread: 4 at 1734364099022
3. one second gone on thread: 1 at 1734364099053
4. one second gone on thread: 1 at 1734364100064
5. one second gone on thread: 1 at 1734364101077
6. one second gone on thread: 1 at 1734364102078
这看起来棒极了!
但这不是我认为
await
与 Task.Run()
和 Parallel.Foreach
应该一起使用的方式。我怎样才能改进这个代码?
提前致谢!
我想你想做的是这样的:
Console.WriteLine($"Before ParallelForeach on thread: {Environment.CurrentManagedThreadId}"); //Main debug 1
var parallelTask = TaskContainingParallelForeach();
Console.WriteLine($"After ParallelForeach on thread: {Environment.CurrentManagedThreadId}"); //Main debug 2
int counter = 0;
while (counter < 7) {
Console.WriteLine($"{counter}. one second gone on thread: {Environment.CurrentManagedThreadId} at {DateTimeOffset.Now.ToUnixTimeMilliseconds()}");
Thread.Sleep(1000);
counter++;
}
await parallelTask; // want to join here