首页 > 代码库 > aync await 进一步探索
aync await 进一步探索
aync await 进一步探索
首先来个例子
class Program{static int index = 1;static void Log(string str){Console.WriteLine((index++) + ". " + str + ". ThreadId:" + Thread.CurrentThread.ManagedThreadId);} static void Main(string[] args) { //解决.net core控制台输出中文乱码的代码 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); //async 不能用于Main方法,所以在这里单独使用一个方法来调用,各位可以试试,编译不过,但VS就是不会告诉你错误在哪里 ExcuteAsync(); Console.ReadLine(); } static async void ExcuteAsync() { Log("异步方法调用前"); var ret = AsyncMethod(); Log("异步方法调用后"); Log(await ret); Log("异步方法使用await后"); } static async Task<string> AsyncMethod() { Log("异步方法开始"); var task = Task.Run<string>(() => { Log("异步方法内部开始"); Thread.Sleep(3000); Log("异步方法内部结束"); return "来自异步方法内部的结果"; }); Log("异步方法结束"); var ret = await task; Log("异步方法await结束"); return ret; } }
控制台输出结果
1. 异步方法调用前. ThreadId:12. 异步方法开始. ThreadId:13. 异步方法结束. ThreadId:14. 异步方法内部开始. ThreadId:35. 异步方法调用后. ThreadId:16. 异步方法内部结束. ThreadId:37. 异步方法await结束. ThreadId:38. 来自异步方法内部的结果. ThreadId:39. 异步方法使用await后. ThreadId:3
分析
为了描述更方便,为每条输出都添加了序号。 为了更清晰的知道每一步的执行顺序以及所在的线程,均添加了ThreadId
- 第1条输出,主线程,没有什么特别的。
- 第2条输出,主线程,说明:调用异步方法本身并不会另起一个线程,如果这里面没有await的话,调用这个方法和调用普通方法没有任何区别。
- 第3条输出,主线程,说明:执行异步方法后主线程并没有被挂起,而是直接继续往下走。
- 第4条输出,线程3(代表子线程,不一定每次都是3),代码显示的要起用一个新线程,没有什么特别的。
- 第5条输出,主线程,和第3条一样,主线程继续往下走,只是代码在不同的方法里而已。
- 第6条输出,线程3,内部执行结束,没什么特别。
- 第7条输出,线程3,说明:这里有一个不同的地方,使用了await,可见,这里是子线程的延续
- 第8-9条输出,线程3,和第7条一样,延续了子线程。
变种
我们把ExcuteAsync方法里的await ret,改成ret.Result看看效果
1. 异步方法调用前. ThreadId:12. 异步方法开始. ThreadId:13. 异步方法结束. ThreadId:14. 异步方法内部开始. ThreadId:35. 异步方法调用后. ThreadId:16. 异步方法内部结束. ThreadId:37. 异步方法await结束. ThreadId:38. 来自异步方法内部的结果. ThreadId:19. 异步方法使用await后. ThreadId:1
第8-9条输出线程变了,可见是主线程被挂起了,等待子线程结束后继续往下执行。那么如果在AsyncMethod里也使用Result,效果又是什么样的?
我们把AsyncMethod方法里的await task改成task.Result,看输出结果
1. 异步方法调用前. ThreadId:12. 异步方法开始. ThreadId:13. 异步方法结束. ThreadId:14. 异步方法内部开始. ThreadId:35. 异步方法内部结束. ThreadId:36. 异步方法await结束. ThreadId:17. 异步方法调用后. ThreadId:18. 来自异步方法内部的结果. ThreadId:19. 异步方法使用await后. ThreadId:1
现在只有Task内部的输出是在子线程了。可见,使用Result的话会失去异步的效果,换句话说,使用Result就不再是异步调用了。
附:文笔不好,只能用习惯的代码来描述,希望能给读者带来帮助。
?
aync await 进一步探索
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。