异步与多线程是不同的概念
异步并不意味着多线程,单线程同样可以异步。
异步默认借助线程池。
多线程经常会有阻塞的操作,而异步要求不阻塞。
异步与多线程适用场景不同
多线程:
- 适合CPU密集型操作
- 适合长期运行的任务
- 线程的创建与销毁的开销是比较大的
- 提供更底层的控制,操作线程、锁、信号量等
- 线程不利于传参和返回
- 线程的代码书写较为繁琐
异步:
- 适合IO密集型操作
- 适合短暂的小任务
- 避免线程阻塞,提高系统的响应能力
什么是异步任务(Task)
开启异步任务之后,当前线程并不会阻塞,而是可以去做其他的事情。
异步任务默认会借助线程池在其他线程上运行。
获取结果后回到之前的状态。
任务的结果:
- 返回值为
Task
的方法表示异步任务没有返回值 - 返回值为
Task<T>
的方法表示有类型为T的返回值
异步方法(async Task)
- 将方法标记
async
后,可以在方法中使用关键字await
await
关键字会等待异步任务的结束,并获得结果async
+await
会将方法包装成状态机,await
类似于检查点async Task
的返回值依旧是Task类型,但是在其中可以使用await关键字。在其中写返回值可以直接写Task<T>
中的T类型。
重要思想:不阻塞
await
会暂时释放当前线程,使得该线程可以执行其他工作,而不必阻塞线程直到异步操作完成。
不要在异步方法里用任何方式阻塞当前线程。
为什么在异步编程中,不使用Thread.Sleep,而是Task.Delay
Task.Delay是一个不阻塞的异步任务,而Thread.Sleep则真正的阻塞了当前线程一段时间
同步上下文
- ConfigureAwait(false),配置任务通过await方法结束后是否回到原来的线程,默认是true。
- TaskScheduler,控制Task的调度方式和运行线程。就像长时间运行线程LongRunning,因为Task默认一般处理比较短的任务,如果任务耗时比较长,可以标记成“长时间运行线程”
如何创建异步任务
- Task.Run()
- Task.Factory.StartNew(),提供更多功能,比如TaskCreationOptions.LongRunning,上一个Run是该方法的简略版
- new Task + Task.Start()
如何同时开启多个异步任务
var inputs = Enumerable.Range(1, 10).ToArray(); var tasks = new List<Task<int>>(); foreach(var input in inputs) { tasks.Add(HeavyJob(input)); } await Task.WhenAll(tasks); var outputs = tasks.Select(x => x.Result).ToArray(); outputs.Dump(); async Task<int> HeavyJob(int input) { await Task.Delay(1000); return input*input; }
异步任务如何取消
使用CancellationToken
推荐异步方法都带上CancellationToken
var cts = new CancellationTokenSource(); try { var task = Task.Delay(10000, cts.Token); Thread.Sleep(2000); cts.Cancel(); await task; } catch(TaskCanceledException) { "Task.Canceled".Dump(); } finally { cts.Dispose(); }
异步一定是多线程?
异步编程不必需要多线程来实现:时间片轮转调度。
单线程异步:自己定好计时器,到时间之前先去做别的事情。
多线程异步:将任务交给不同的线程,并有自己来指挥调度。
异步方法一定要写成async Task吗
不一定。async只是配合await来使用,将方法包装成状态机。
开启的异步任务一定不会阻塞当前线程?
await关键字不一定会立即释放当前线程,所以如果调用的异步方法中存在阻塞(如Thread.Sleep(0)),那么依旧会阻塞当前上下文对应的线程。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!