异步执行:
1、通过单线程实现并发操作。任务在等待I/O(网络、文件)时,不会阻塞其他任务的执行
2、更节省系统资源,不需要常见多个线程
3、适合I/O密集型任务,如网络请求,数据库查询等
4、示例
using System;
using System.Threading.Tasks;
class Program
{
static async Task Task1Async()
{
Console.WriteLine("任务1开始");
await Task.Delay(3000); // 模拟异步耗时操作
Console.WriteLine("任务1完成");
}
static async Task Task2Async()
{
Console.WriteLine("任务2开始");
await Task.Delay(3000); // 模拟异步耗时操作
Console.WriteLine("任务2完成");
}
static async Task Main(string[] args)
{
// 并发执行任务1和任务2
Task task1 = Task1Async();
Task task2 = Task2Async();
await Task.WhenAll(task1, task2); // 等待所有异步任务完成
Console.WriteLine("所有任务完成");
}
}
输出
任务1开始
任务2开始
任务1完成
任务2完成
所有任务完成
解释
·两个任务几乎同时开始,并且各自等待完成。总耗时大约为 3 秒,因为它们是并发执行的
多线程:
1、通过创建多个线程并行执行任务,每个任务都可以独立运行并充分利用多个 CPU 核心。
2、在某些场景下(如大量计算),多线程执行可以真正地实现任务并行处理。
3、适合CPU 密集型任务,例如复杂的计算和数据处理等。
4、示例
using System;
using System.Threading;
class Program
{
static void Task1()
{
Console.WriteLine("任务1开始");
Thread.Sleep(3000); // 模拟耗时操作
Console.WriteLine("任务1完成");
}
static void Task2()
{
Console.WriteLine("任务2开始");
Thread.Sleep(3000); // 模拟耗时操作
Console.WriteLine("任务2完成");
}
static void Main()
{
Thread thread1 = new Thread(Task1);
Thread thread2 = new Thread(Task2);
// 启动线程
thread1.Start();
thread2.Start();
// 等待线程结束
thread1.Join();
thread2.Join();
Console.WriteLine("所有任务完成");
}
}
输出
任务1开始
任务2开始
任务1完成
任务2完成
所有任务完成
解释:任务1和任务2在各自的线程上并行运行。总耗时大约为 3 秒。
练习:
区分Task.Delay(3000).Wait()
、await Task.Delay(3000)
和 Thread.Sleep(3000)
1、Thread.Sleep(3000)
同步阻塞,程序执行被阻塞,等待3秒后继续,程序“卡住”
2、Task.Delay(3000)
异步阻塞,程序执行继续,完全没影响
3、await Task.Delay(3000) 异步阻塞,程序执行被暂停,等待3秒后继续,但是程序不是“卡住”,
当前线程可以去执行其他任务,而不是被“卡住”在某个等待操作上
表现:暂停期间,线程空闲出来可以处理其他任务,等异步任务完成后,程序会继续执行挂起的部分(回调)
4、Task.Delay(3000).Wait() 调用wait办法,将异步阻塞变为同步阻塞!