簡體   English   中英

使用 Task.WaitAll() 來處理等待的任務?

[英]Use Task.WaitAll() to handle awaited tasks?

理想情況下,我想要做的是使用非阻塞模式延遲任務,然后等待所有任務完成。 我嘗試添加 Task.Delay 返回的任務對象,然后使用 Task.WaitAll 但這似乎無濟於事。 我應該如何解決這個問題?

class Program
{
    public static async void Foo(int num)
    {
        Console.WriteLine("Thread {0} - Start {1}", Thread.CurrentThread.ManagedThreadId, num);

        var newTask = Task.Delay(1000);
        TaskList.Add(newTask);
        await newTask;

        Console.WriteLine("Thread {0} - End {1}", Thread.CurrentThread.ManagedThreadId, num);
    }

    public static List<Task> TaskList = new List<Task>();

    public static void Main(string[] args)
    {
        for (int i = 0; i < 3; i++)
        {
            int idx = i;
            TaskList.Add(Task.Factory.StartNew(() => Foo(idx)));
        }

        Task.WaitAll(TaskList.ToArray());
    }
}

這是你想要達到的目標嗎?

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

namespace ConsoleApplication
{
    class Program
    {
        public static async Task Foo(int num)
        {
            Console.WriteLine("Thread {0} - Start {1}", Thread.CurrentThread.ManagedThreadId, num);

            await Task.Delay(1000);

            Console.WriteLine("Thread {0} - End {1}", Thread.CurrentThread.ManagedThreadId, num);
        }

        public static List<Task> TaskList = new List<Task>();

        public static void Main(string[] args)
        {
            for (int i = 0; i < 3; i++)
            {
                int idx = i;
                TaskList.Add(Foo(idx));
            }

            Task.WaitAll(TaskList.ToArray());
            Console.WriteLine("Press Enter to exit...");
            Console.ReadLine();
        }
    }
}

輸出:

Thread 10 - Start 0
Thread 10 - Start 1
Thread 10 - Start 2
Thread 6 - End 0
Thread 6 - End 2
Thread 6 - End 1
Press Enter to exit...

需要注意的是,因為 Foo 是異步的,所以它本身就是一個任務。 您的示例具有簡單地啟動Foo任務的任務,但不要等待它。

換句話說, Task.WaitAll(TaskList.ToArray())只是在等待每個Task.Delay開始,而不是等待所有這些任務完成。

這可能是您想要實現的目標:

class Program
{
    public static async Task Foo(int num)
    {
        Console.WriteLine("Thread {0} - Start {1}", Thread.CurrentThread.ManagedThreadId, num);

        var newTask = Task.Delay(1000);

        await newTask;
        Console.WriteLine("Thread {0} - End {1}", Thread.CurrentThread.ManagedThreadId, num);

    }

    public static List<Task> TaskList = new List<Task>();

    public static void Main(string[] args)
    {
        for (int i = 0; i < 3; i++)
        {
            int idx = i;

            Task fooWrappedInTask = Task.Run(() => Foo(idx));
            TaskList.Add(fooWrappedInTask);
        }

        Task.WaitAll(TaskList.ToArray());
        Console.WriteLine("Finished waiting for all of the tasks: - Thread {0}", Thread.CurrentThread.ManagedThreadId);
    }
}

我已經對此進行了測試,它會生成您想要的控制台輸出。


這里的主要區別是我們調用的是Task.Run而不是Task.Factory.StartNew

你可能有一個Task返回一個Task ,甚至可能返回另一個Task 你會認為這是一個“鏈”的任務。

Task.Run返回Task是代表在鏈中的最后一項任務。 當您等待它時,您正在等待任務鏈中的每個環節完成。

相比之下, Task.Factory.StartNew返回一個代表鏈中第一個鏈接的任務。 等待之后,剩下的就是鏈條的其余部分了。 Task返回的內容不是另一個Task的情況下,這很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM