上图的所有多线程案例大全完整版本项目源代码下载---->点击下载
在C#中等待所有线程(List)运行结束后触发事件,有以下特点:
- 确保所有任务完成:通过等待所有线程(Task)完成后才触发事件,可以确保所有任务都已经完成。这样可以避免在某些任务未完成的情况下继续执行后续代码,可能导致的不一致或错误。
- 同步操作:在某些情况下,可能需要在所有任务完成后进行一些操作,如汇总结果、处理返回值等。通过等待所有线程结束,可以同步这些操作,确保它们在所有任务完成后一起执行。
- 防止线程资源泄露:对于非守护线程,如果主线程结束而其他线程仍在运行,则它们可能会被强制终止。等待所有线程完成可以确保不会因主线程结束而导致其他线程被强制终止,避免了可能的资源泄露问题。
- 提高代码可读性:通过使用异步编程和等待所有任务完成的操作,可以使代码更加简洁、易于阅读和理解。这样的代码通常更易于维护和扩展。
- 充分利用多核CPU:通过使用多线程,可以充分利用多核CPU的并行处理能力,加快任务的执行速度。尤其在处理大量数据或进行密集计算时,使用多线程可以显著提高程序的性能。
- 异常处理:通过等待所有线程完成并捕获其中的异常,可以集中处理所有线程中可能发生的异常,避免某些异常被忽略或抛出而未被捕获导致程序不稳定。
在C#中,你可以使用Task.WhenAll、Task.WaitAll等
方法来等待所有Task
完成,然后触发某个事件。以下是一个简单的示例:
private void button1_Click(object sender, EventArgs e)
{
List<Task> ts = new List<Task>();
for (int i = 0; i < 5; i++)
{
ts.Add(Task.Run(() =>
{
//list里面多人线程可以同时跑
Thread.Sleep(1000);
Console.WriteLine($"素菜做好了{Thread.CurrentThread.ManagedThreadId}");
}));
ts.Add(Task.Run(() =>
{
//list里面多人线程可以同时跑
Thread.Sleep(2000);
Console.WriteLine($"荤菜做好了{Thread.CurrentThread.ManagedThreadId}");
}));
}
Task.WhenAll(ts).ContinueWith(t =>
{
//当list线程结束后再运行下面的内
Console.WriteLine($"菜都做好了,大家快来吃饭!{Thread.CurrentThread.ManagedThreadId}");
});
Console.WriteLine($"主线程结束,主线程-->{Thread.CurrentThread.ManagedThreadId}");
}
private void button2_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
Console.WriteLine($"正在运行线程-->{Thread.CurrentThread.ManagedThreadId}");
List<Task> ts = new List<Task>();
for (int i = 0; i < 5; i++)
{
ts.Add(Task.Run(() =>
{
//list里面多人线程可以同时跑
Thread.Sleep(1000);
Console.WriteLine($"素菜做好了,线程-->{Thread.CurrentThread.ManagedThreadId}");
}));
ts.Add(Task.Run(() =>
{
//list里面多人线程可以同时跑
Thread.Sleep(2000);
Console.WriteLine($"荤菜做好了{Thread.CurrentThread.ManagedThreadId}");
}));
}
Task.WaitAll(ts.ToArray());//阻塞到全部Task完成---不卡界面的特性丢失了,因为主线程在等待呀
Console.WriteLine($"菜都做好了,大家快来吃饭!{Thread.CurrentThread.ManagedThreadId}");
});
}