任务 WaitAll return C# 中的列表对象

Task WaitAll return List object in c#

我创建这段代码是为了理解 c# 中的“Task.WaitAll ()”。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;

namespace taskApp
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Task> p = new List<Task>();

            Task task1 = MultipleTasks();
            Task task2 = Hello(40);
            Task task3 = Bye(10);
            Task.WaitAll(task1, task2, task3);

            var a = 1;
            a = a + 1;
        }

        private static async Task Hello(int delay)
        {
            await Task.Delay(delay);
            Console.WriteLine($"+++ End Process: {nameof(Hello)}, delay: {delay} +++ ");
        }

        private static async Task Bye(int delay)
        {
            await Task.Delay(delay);
            Console.WriteLine($"+++ End Process: {nameof(Bye)}, delay: {delay} +++ ");
        }
        private static async Task<List<MyClass>> MultipleTasks()
        {
            List<Task<MyClass>> psTask = new List<Task<MyClass>>();
            List<MyClass> ps = new List<MyClass>();

            for (int i = 0; i < 3; i++)
                psTask.Add(getTest(i));

            Task.WaitAll(psTask.ToArray());

            ps = psTask.Select(c => c.Result).ToList();

            return ps;
        }

        private static async Task<MyClass> getTest(int i)
        {
            MyClass p = new MyClass();
            int delay = 0;
            switch (i)
            {
                case 0:
                    delay = 4000;
                    p.delayUsed = delay;
                    p.message = "cero";
                    break;
                case 1:
                    delay = 1000;
                    p.delayUsed = delay;
                    p.message = "uno";
                    break;
                case 2:
                    delay = 7000;
                    p.delayUsed = delay;
                    p.message = "dos";
                    break;
                case 3:
                    delay = 2000;
                    p.delayUsed = delay;
                    p.message = "tres";
                    break;
                default:
                    p.message = "default";
                    break;
            }

            await Task.Delay(p.delayUsed);
            Console.WriteLine($"+++ End Process: {nameof(getTest)} {i}, delay: {delay} +++ ");
            return p;
        }
    }

    public class MyClass
    {
        public int delayUsed { get; set; }
        public string message { get; set; }
    }
}

这是控制台应用程序 运行s

的顺序
+++ End Process: getTest 1, delay: 1000 +++
+++ End Process: getTest 0, delay: 4000 +++
+++ End Process: getTest 2, delay: 7000 +++
+++ End Process: Bye, delay: 10 +++
+++ End Process: Hello, delay: 40 +++

我的应用程序应该运行的正确顺序如下:

+++ End Process: Bye, delay: 10 +++
+++ End Process: Hello, delay: 40 +++
+++ End Process: getTest 1, delay: 1000 +++
+++ End Process: getTest 0, delay: 4000 +++
+++ End Process: getTest 2, delay: 7000 +++

按照各个方法延迟时间的逻辑,推导出正确的执行顺序

enter image description here

这就是“visual studio2019”给我的帮助

并且有效地同步执行“MultipleTasks()”方法。

谁能告诉我如何让控制台应用程序正常运行?

问题是您在任务创建期间等待,而不仅仅是任务执行。

首先,将您的 MultipleTasks() 方法更改为如下所示(returning List<Task>):

    private static List<Task> MultipleTasks()
    {
        List<Task> psTask = new List<Task>();

        for (int i = 0; i < 3; i++)
            psTask.Add(getTest(i));

        return psTask;
    }

然后把getTest()方法改成returnTask,像这样:

    private static async Task getTest(int i)
    {
        // snip

        await Task.Delay(p.delayUsed);
        Console.WriteLine($"+++ End Process: {nameof(getTest)} {i}, delay: {delay} +++ ");
    }

最后,像这样创建并执行您的任务:

    static void Main(string[] args)
    {
        var tasks = MultipleTasks();

        tasks.Add(Hello(40));
        tasks.Add(Bye(10));
        
        Task.WaitAll(tasks.ToArray());

        Console.ReadKey();
    }

那么输出应该就是您要查找的内容:

这就是我想要实现的,非常感谢你的帮助。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;

namespace taskApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++ ");
            Console.WriteLine($"+++ Asynchronous code +++ ");
            Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++ ");
            List<Task<MyClass>> tasks = MultipleTasks();
            Task<MyClass> task2 = Hello(400);
            Task<MyClass> task3 = Bye(10);

            tasks.Add(task3);
            tasks.Add(task2);

            Task.WaitAll(tasks.ToArray());

            //from here it runs synchronously

            MyClass a = task2.Result;
            MyClass b = task3.Result;

            List<MyClass> c = tasks.Select(c => c.Result).ToList();
            Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++ ");
            Console.WriteLine($"+++ Synchronous code ++++ ");
            Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++ ");
            Console.WriteLine($"+++ Run {nameof(task2)}: message {a.message}, delay {a.delayUsed}+++ ");
            Console.WriteLine($"+++ Run {nameof(task3)}: message {b.message}, delay {b.delayUsed}+++ ");
            Console.WriteLine();

            foreach (var item in c)
            {
                Console.WriteLine($"+++ Run {nameof(tasks)}: message: {item.message}, delay {item.delayUsed} +++ ");
            }
            Console.WriteLine($"++++++++++++++++++++++++++++++++++++++++ ");
        }

        private static async Task<MyClass> Hello(int delay)
        {
            MyClass p = new MyClass();
            p.delayUsed = delay;
            p.message = $"Procedure {nameof(Hello)}";

            await Task.Delay(delay);
            Console.WriteLine($"+++ End Process: {nameof(Hello)}, delay: {delay} +++ ");
            return p;
        }

        private static async Task<MyClass> Bye(int delay)
        {
            MyClass p = new MyClass();
            p.delayUsed = delay;
            p.message = $"Procedure {nameof(Bye)}";
            await Task.Delay(delay);
            Console.WriteLine($"+++ End Process: {nameof(Bye)}, delay: {delay} +++ ");
            return p;
        }
        private static List<Task<MyClass>> MultipleTasks()
        {
            List<Task<MyClass>> psTask = new List<Task<MyClass>>();

            for (int i = 0; i < 3; i++)
                psTask.Add(getTest(i));

            return psTask;
        }

        private static async Task<MyClass> getTest(int i)
        {
            MyClass p = new MyClass();
            int delay = 0;
            switch (i)
            {
                case 0:
                    delay = 4000;
                    p.delayUsed = delay;
                    break;
                case 1:
                    delay = 1000;
                    p.delayUsed = delay;
                    break;
                case 2:
                    delay = 7000;
                    p.delayUsed = delay;
                    break;
                case 3:
                    delay = 2000;
                    p.delayUsed = delay;
                    break;
                default:
                    delay = 0;
                    break;
            }

            p.message = $"Procedure {nameof(getTest)}({i})";
            await Task.Delay(p.delayUsed);
            Console.WriteLine($"+++ End Process: {nameof(getTest)}({i}), delay: {delay} +++ ");
            return p;
        }
    }

    public class MyClass
    {
        public int delayUsed { get; set; }
        public string message { get; set; }
    }
}

结果

++++++++++++++++++++++++++++++++++++++++
+++ Asynchronous code +++
++++++++++++++++++++++++++++++++++++++++
+++ End Process: Bye, delay: 10 +++
+++ End Process: Hello, delay: 400 +++
+++ End Process: getTest(1), delay: 1000 +++
+++ End Process: getTest(0), delay: 4000 +++
+++ End Process: getTest(2), delay: 7000 +++
++++++++++++++++++++++++++++++++++++++++
+++ Synchronous code ++++
++++++++++++++++++++++++++++++++++++++++
+++ Run task2: message Procedure Hello, delay 400+++
+++ Run task3: message Procedure Bye, delay 10+++

+++ Run tasks: message: Procedure getTest(0), delay 4000 +++
+++ Run tasks: message: Procedure getTest(1), delay 1000 +++
+++ Run tasks: message: Procedure getTest(2), delay 7000 +++
+++ Run tasks: message: Procedure Bye, delay 10 +++
+++ Run tasks: message: Procedure Hello, delay 400 +++
++++++++++++++++++++++++++++++++++++++++