Parallel与Task的联合使用

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);  
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值