多线程 - For 循环不等待 Await

MultiThreading - For loop doesnt waits on Await

我有一个控制台应用程序有两个线程:

    public static async void Thread1()
        {
            for (int i = 0; i < 100; i++)
            {
                Debug.WriteLine("Thread1 " + i);
                await MyFunc();
            }
        }

    public static async void Thread2()
        {
            for (int i = 0; i < 100; i++)
            {
                Debug.WriteLine("Thread2 " + i);
                await MyFunc();
            }
        }
    public static void Main(string[] args)
        {
            MainAsync(args).GetAwaiter().GetResult();
        }
    private static async Task MainAsync(string[] args)
        {

            Console.WriteLine("Before start thread");

            Thread tid1 = new Thread(Thread1);
            Thread tid2 = new Thread(Thread2);

            tid1.Start();

            tid2.Start();
        }

    public static async Task MyFunc()
        {
         //do something
        }

但是,当应用程序 运行 并终止时,似乎只有每个线程 运行 一次,因为我只在输出中看到以下内容:

 Before start thread
    Thread1 0
    Thread2 0
//some thing from MyFunc

我希望或更愿意 运行 每个线程,直到 for loop.It 在我看来 for 循环继续 运行 尽管等待。 如果是,其他可能的方法是什么。

任何线索都会有所帮助。

使用异步 Task 而不是 async void

private static async Task MainAsync(string[] args)
{
    Console.WriteLine("Before start thread");
    var task1 = Thread1();
    var task2 = Thread2();
    var taskList = new [] { task1, task2 };
    Task.WaitAll(taskList);
}

您似乎对线程和任务的作用有很多困惑,因此最好阅读一下。 Steven Cleary has a nice write-up about this. "There Is No Thread"

从评论来看,您的实际意图似乎是 运行 并行执行两个 async 任务,然后等待它们都完成。

如果您想等待两个异步任务并行完成,请确保您的 async 方法实际 return Task 然后:

Task task1 = DoSomethingAsync(); //don't await
Task task2 = DoSomethingElseAsync(); //don't await

那么你可以异步等待 Task.WhenAll:

await Task.WhenAll(task1,task2);

你真的根本不需要参与 Thread

您没有做任何事情来等待线程。主例程将继续,直到 returns 到 O/S,这将终止进程和所有子线程。由于您没有做任何其他事情,这几乎会立即发生,从而缩短两个线程的生命周期。

如果你想等待线程完成,你可以参考this answer写一些

的变体
while (thread1.IsAlive || thread2.IsAlive)
{
    //Do something to wait
}

...退出前。

也就是说,您可能应该使用任务而不是线程,例如

public static async Task Task1()
{
    for (int i = 0; i < 100; i++)
    {
        Debug.WriteLine("Task1 " + i);
        await MyFunc();
    }
}

public static async Task Task2()
{
    for (int i = 0; i < 100; i++)
    {
        Debug.WriteLine("Task2 " + i);
        await MyFunc();
    }
}

然后执行并等待它们:

Task.WaitAll
( 
    new[] 
    {
        Task1(), 
        Task2() 
    } 
);

See this code in action on DotNetFiddle

另见 What is the difference between tasks and threads?