初步学习async/await,Task.GetAwaiter,Task.Result
网上关于async/await的知识有很多,看了很多但不如自己实践一遍来得快,所以这里记录下我的理解和大家学习下。
首先以最简单的同步方法来开始如下
private static void Test() { Console.WriteLine(2); GetV(); Console.WriteLine(6); } private static void GetV() { Console.WriteLine(3); Console.WriteLine(4); Console.WriteLine(5); } static void Main(string[] args) { Console.WriteLine(1); Test(); Console.WriteLine(7); }
输出如下
当时当我们简单的使用Task.Run时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | private static void Test() { Console.WriteLine(2); GetV(); Console.WriteLine(6); } private static void GetV() { Console.WriteLine(3); Task.Run(() => { Thread.Sleep(10000); Console.WriteLine(4); }); Console.WriteLine(5); } static void Main( string [] args) { Console.WriteLine(1); Test(); Console.WriteLine(7); } |
,因为分配了新的线程,所以4会最晚打印出来。
这时候我们使用async/await呢?
private static async Task Test() { Console.WriteLine(2); await GetV(); Console.WriteLine(6); } private static async Task GetV() { Console.WriteLine(3); await Task.Run(() => { Thread.Sleep(10000); Console.WriteLine(4); }); Console.WriteLine(5); } static void Main(string[] args) { Console.WriteLine(1); var v= Test(); Console.WriteLine(7); }
因为await会时被修饰的代码处于等待状态,就相当于阻塞那段代码,Test方法里面执行到await时就会等待Getv的方法的执行,就会阻塞Test方法,但是不会阻塞Main方法,可以理解为await将阻塞的控制权交给了Test方法。所以这个时候打印结果为
但是当我们把Test的await去掉了,这时候Test方法就没有了阻塞的权限,而是去寻找下一个await来转移控制权,如下
private static void Test() { Console.Out.WriteLine(2); GetV(); Console.Out.WriteLine(6); } private static async Task GetV() { Console.Out.WriteLine(3); await Task.Run(() => { Thread.Sleep(10000); Console.WriteLine(4); }); Console.Out.WriteLine(5); } static void Main(string[] args) { Console.Out.WriteLine(1); Test(); Console.Out.WriteLine(7); string str = Console.ReadLine(); }
这个时候就不会阻塞Test方法,结果如下
如果在main方法里面使用Task.GetAwaiter或者Task.Result呢,这两个东西我的理解就是阻塞线程,等待异步返回结果,但是它阻塞的是当前的方法,如下代码
private static async Task Test() { Console.Out.WriteLine(2); GetV(); Console.Out.WriteLine(6); } private static async Task GetV() { Console.Out.WriteLine(3); await Task.Run(() => { Thread.Sleep(10000); Console.WriteLine(4); }); Console.Out.WriteLine(5); } static void Main(string[] args) { Console.Out.WriteLine(1); Test().GetAwaiter().GetResult() ; Console.Out.WriteLine(7); string str = Console.ReadLine(); }
它只会阻塞main方法的,但是对于Test方法它是无法阻塞的,Test方法仍然会异步执行,4,5仍然以异步的方法打印出来,所以打印结果如下
Task.Result也是如此,只会阻塞当前的方法,我觉得和await相似,只给了当前使用Task.GetAwaiter或者Task.Result的方法阻塞全,没有权利阻塞别的方法。
打个广告:游戏也能赚钱?如果你热爱游戏,并且想通过游戏赢得零花钱,5173是个不错的选择
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 基于DeepSeek R1 满血版大模型的个人知识库,回答都源自对你专属文件的深度学习。
· 在缓慢中沉淀,在挑战中重生!2024个人总结!
· 大人,时代变了! 赶快把自有业务的本地AI“模型”训练起来!