MultiThreading - For循环不会等待等待

时间:2018-03-08 01:43:12

标签: c# multithreading for-loop locking semaphore

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

    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循环。在我看来,尽管等待,for循环仍在继续运行。 如果是,可能是其他可能的方法。

任何线索都会有所帮助。

3 个答案:

答案 0 :(得分:2)

你似乎对线程和任务的作用有很多困惑,因此阅读它是一个好主意。 Steven Cleary对此有一个很好的描述。 "There Is No Thread"

从评论中看来,你的实际意图似乎是并行运行两个NULL任务,然后等到它们都完成了。

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

Task

然后您可以异步等待Task.WhenAll

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

您根本不需要涉及await Task.WhenAll(task1,task2);

答案 1 :(得分:2)

你没有做任何事情来等待线程。主例程将继续,直到它返回到O / S,这将终止进程和任何子线程。由于你不做任何其他事情,这几乎立即发生,削减了两个线程&#39;生活得很短。

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

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

...退出之前。

话虽这么说,你应该使用Tasks而不是线程,例如

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?

答案 2 :(得分:1)

使用异步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);
}