简体   繁体   English

Task.Run与Task.WhenAll与Parallel.Invoke与其他:并行运行任务并在C#中获取结果

[英]Task.Run vs Task.WhenAll vs Parallel.Invoke vs others: Run tasks in parallel and Get result in C#

Is the code in Option 1 below the best way to achieve in running tasks in parallel? 下面的选项1中的代码是否是并行运行任务的最佳方法?

Option 1 选项1

var w = Task.Run(async () => await Work1());
var w2 = Task.Run(async () => await Work2());
Console.WriteLine("end: " + DateTime.Now.ToString("hh:mm:ss.fff"));
await w;
await w2;
Console.WriteLine("last: " + DateTime.Now.ToString("hh:mm:ss.fff") + " " + w.Result + " " + w2.Result);
Console.WriteLine("end");

Result: 结果:

end: 06:07:13.054
Work2 s 06:07:13.057
Work1 s 06:07:13.057
Work1 e 06:07:16.072
Work2 e 06:07:17.066
last: 06:07:17.066 1 2

option 2: It swithes to other work upon await, ie. 选项2:在等待时将其转为其他工作。 not really in parallel. 并非真正并行。

            var tasks = new List<Task<int>>();
            tasks.Add(Work1());
            tasks.Add(Work2());
            Console.WriteLine("end: " + DateTime.Now.ToString("hh:mm:ss.fff"));
            await Task.WhenAll(tasks);
            Console.WriteLine("end2: " + DateTime.Now.ToString("hh:mm:ss.fff"));
            Console.WriteLine("last: " + DateTime.Now.ToString("hh:mm:ss.fff") + " " + tasks[0].Result + " " + tasks[1].Result);

Result: 结果:

Work1 s 06:11:42.565
Work2 s 06:11:44.571
Work1 e 06:11:45.579
end: 06:11:47.572
Work2 e 06:11:48.574
end2: 06:11:48.575
last: 06:11:48.579 1 2

Tasks 任务

  private static async Task<int> Work1()
        {
            Console.WriteLine("Work1 s " + DateTime.Now.ToString("hh:mm:ss.fff"));
            Thread.Sleep(2000);
            await Task.Delay(1000);
            Console.WriteLine("Work1 e " + DateTime.Now.ToString("hh:mm:ss.fff"));
            return 1;
        }

        private static async Task<int> Work2()
        {
            Console.WriteLine("Work2 s " + DateTime.Now.ToString("hh:mm:ss.fff"));
            Thread.Sleep(3000);
            await Task.Delay(1000);
            Console.WriteLine("Work2 e " + DateTime.Now.ToString("hh:mm:ss.fff"));
            return 2;
        }

Parallel.Invoke() doesn't return result. Parallel.Invoke()不返回结果。

Parallel.Invoke() accepts params Action[] that mean you need to pass an list, if to be more accurate - array of actions, action to it. Parallel.Invoke()接受params Action[] ,这意味着您需要传递一个列表(如果更准确的话)-动作数组,对其进行动作。 In simpler words you need to pass a method to execute. 用简单的话来说,您需要传递一个方法来执行。 Simply invoking Parallel.Invoke() wont do a thing. 简单地调用Parallel.Invoke()不会做任何事情。

Here is an example from Parallel tutorial 这是并行教程中的一个示例

using System;
using System.Threading.Tasks;

class Program
{
    static void Test()
    {
        Console.WriteLine("Test");
    }

    static void Test2()
    {
        Console.WriteLine("Test2");
    }

    static void Test3()
    {
        Console.WriteLine("Test3");
    }

    static void Main()
    {
        Parallel.Invoke(Test, Test2, Test3);
        Console.WriteLine("[INTERMEDIATE]");
        Parallel.Invoke(Test, Test2, Test3);
    }
}

After reading more carefull your question, more thoughs came to my head. 在仔细阅读了您的问题之后,更多的烦恼浮现在我脑海。 What if you tried to use Parallel.ForEach() ? 如果您尝试使用Parallel.ForEach()怎么办?

It probably could look something like this: 它可能看起来像这样:

Parallel.ForEach(tasks, task =>{
var result = task.Invoke();
//You can do whatever you want with result
});

Assuming that tasks is List<Task<int>> , if to be more precise - IEnumerable<Task<int>> , of tasks that you need to perform. 假设tasksList<Task<int>> ,更确切地说,是您要执行的任务的IEnumerable<Task<int>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM