Parallel是一个静态类,调用静态方法Invoke即可开启多个线程,Invoke方法接收Action委托的数组。
开启多线程会并行执行,直到开启的线程执行完毕,才会继续执行主线程,实现功能类似于Task.WaitAll()
Parallel.Invoke(
() => Console.WriteLine("do something1"),
() => Console.WriteLine("do something2"),
() => Console.WriteLine("do something3"),
() => Console.WriteLine("do something4")
);
Console.WriteLine("main Flow");
控制线程数量
Parallel实现了控制使用线程数量的功能,这在Task,ThreadPool,Thread中都没有实现。
Parallel.Invoke是一个重载方法,其中有一个接收两个参数:
第一个参数接收线程数量的配置,第二个参数是Action数组。
解决Parallel 阻塞主线程问题
使用Task中 即可。
Task.Run(() =>
{
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 3;//设置线程数量
Parallel.Invoke(parallelOptions,
() => Console.WriteLine("do something1"),
() => Console.WriteLine("do something2"),
() => Console.WriteLine("do something3"),
() => Console.WriteLine("do something4"),
() => Console.WriteLine("do something5"),
() => Console.WriteLine("do something6"),
() => Console.WriteLine("do something7")
);
Console.WriteLine("main thread");
});
在C#中,使用Parallel类执行并行任务时,通常会用到Parallel.For或Parallel.ForEach方法。这些方法会自动处理任务的分配和执行,并且会等待所有并行任务完成后才继续执行后续的代码。
如果你需要显式地判断所有并行任务是否已经完成,你可以通过以下几种方式来实现:
使用Parallel方法的同步执行特性:
Parallel.For和Parallel.ForEach方法本身就会等待所有并行任务完成后才返回。因此,你可以直接在这两个方法调用之后编写后续代码,这些代码会在所有任务完成后执行。
使用Task和Task.WaitAll:
如果你使用的是Task来执行并行任务,你可以将所有任务存储在一个Task[]数组中,然后使用Task.WaitAll方法来等待所有任务完成。
Task[] tasks = new Task[3];
tasks[0] = Task.Run(() => { /* 任务1的代码 */ });
tasks[1] = Task.Run(() => { /* 任务2的代码 */ });
tasks[2] = Task.Run(() => { /* 任务3的代码 */ });
Task.WaitAll(tasks); // 等待所有任务完成
使用ParallelLoopState:
在Parallel.For或Parallel.ForEach的循环体中,你可以使用ParallelLoopState参数来访问当前循环的状态,包括是否应该停止或中断循环。然而,这个状态并不直接提供所有任务是否已完成的信息,因为Parallel方法本身会等待所有任务完成。
使用async和await与Task结合:
如果你的方法是异步的,并且你使用了Task来执行并行任务,你可以使用await Task.WhenAll来等待所有任务完成。
await Task.WhenAll(task1, task2, task3); // 等待所有任务完成
在C#中,Task 是一种表示异步操作的方式,通常与 async 和 await 关键字一起使用来实现异步编程。然而,在某些情况下,你可能需要在同步方法中使用 Task,比如当你调用一个返回 Task 的异步方法,但你目前处于一个同步上下文中。
等待任务完成:你可以使用 Task.Wait() 或 Task.Result 属性来等待异步任务完成,并获取其结果。这种方式会阻塞当前线程,直到任务完成。
public void SyncMethod()
{
Task<int> task = SomeAsyncMethod(); // 假设这是一个返回Task<int>的异步方法
task.Wait(); // 等待任务完成
int result = task.Result; // 获取任务结果
Console.WriteLine(result);
}
使用 Task.Run() 来执行同步代码:如果你想要在一个新的线程中执行同步代码,并且想要以 Task 的形式来处理它,你可以使用 Task.Run() 方法。
public void SyncMethod()
{
Task task = Task.Run(() =>
{
// 放置同步代码
Console.WriteLine("Running synchronous code on a new thread.");
});
task.Wait(); // 等待任务完成
}
使用 async 和 await:如果可能,最好的做法是将方法改为异步的,使用 async 关键字,并在调用异步方法时使用 await。
public async Task AsyncMethod()
{
int result = await SomeAsyncMethod(); // 假设这是一个返回Task<int>的异步方法
Console.WriteLine(result);
}