Async Await (多线程等待) 用写单线程的方式写多线程
Task
n.
任务;(尤指艰巨或令人厌烦的)工作;(尤指语言教学中旨在帮助达到某一学习目的的)活动
vt.
交给某人(任务);派给某人(工作)
//async是修饰方法的:---如果只是在方法上写一个async--警告;---而且没有什么用处;
//awai是在方法内部的:---如果只在方法内部写await,没有async---报错
//async+awai配套使用的
//await后的代码会由线程池的线程执行 非阻塞 并发执行
//主线程到await这里就返回了,执行主线程任务 ,task中的任务执行完毕以后---继续执行await后面的后续内容,有可能是子线程,也有可能是其他线程,甚至有可能是主线程来执行;
原理是底层状态机的实现 有个 MoveNext方法
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 26 27 28 29 30 31 32 | -------------------主线程-------------- private static async void NoReturnNoAwait() { //主线程执行 Task task = Task.Run(() => //启动新线程完成任务 { Thread.Sleep(1000); Console.WriteLine($ "NoReturnNoAwait Sleep3000 before,ThreadId={Thread.CurrentThread.ManagedThreadId}" ); Thread.Sleep(1000); Console.WriteLine($ "NoReturnNoAwait Sleep3000 after,ThreadId={Thread.CurrentThread.ManagedThreadId}" ); }); //主线程执行 Console.WriteLine($ "NoReturnNoAwait Sleep after Task,ThreadId={Thread.CurrentThread.ManagedThreadId}" ); } ------------------子线程无返回值--------- private static async Task NoReturnTask() //在async/await方法里面如果没有返回值,默认返回一个Task { //这里还是主线程的id Console.WriteLine($ "NoReturnTask Sleep before await,ThreadId={Thread.CurrentThread.ManagedThreadId}" ); Task task = Task.Run(() => { Console.WriteLine($ "NoReturnTask Sleep3000 before,ThreadId={Thread.CurrentThread.ManagedThreadId}" ); Thread.Sleep(1000); Console.WriteLine($ "NoReturnTask Sleep3000 after,ThreadId={Thread.CurrentThread.ManagedThreadId}" ); }); await task; //主线程到await这里就返回了,执行主线程任务 ,task中的任务执行完毕以后---继续执行await后面的后续内容,有可能是子线程,也有可能是其他线程,甚至有可能是主线程来执行; Console.WriteLine($ "NoReturnTask Sleep after await,ThreadId={Thread.CurrentThread.ManagedThreadId}" ); //return; //return new TaskFactory().StartNew(() => { }); //不能return 没有async才行 } |
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 26 27 28 29 30 31 32 33 34 35 36 | continueWith 类似于一个回调 意思是继续但是写的很不方便 这里可以和await task等价替换 /// <summary> /// 真的返回Task 不是async /// /// 要使用返回值就一定要等子线程计算完毕 /// </summary> /// <returns>没有async Task</returns> private static Task< int > SumFactory() { Console.WriteLine($ "SumFactory 111 start ManagedThreadId={Thread.CurrentThread.ManagedThreadId}" ); TaskFactory taskFactory = new TaskFactory(); Task< int > iResult = taskFactory.StartNew< int >(() => { Thread.Sleep(3000); Console.WriteLine($ "SumFactory 123 Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}" ); return 123; }).ContinueWith(c=> { Thread.Sleep(3000); Console.WriteLine($ "SumFactory 234 Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}" ); return 123; }).ContinueWith(t=> { Thread.Sleep(3000); Console.WriteLine($ "SumFactory 345 Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}" ); return 123; }); //就是回调来控制线程内部的业务逻辑的执行顺序---不爽 //Console.WriteLine($"This is {iResult.Result}"); Console.WriteLine($ "SumFactory 111 end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}" ); return iResult; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现