多线程 - 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?
我有一个控制台应用程序有两个线程:
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?