普通的async await方法其实是一个同步的异步调用,此方式并不开启新的线程,只是一个多任务处理模式,只是主线程在运行时不会阻塞卡死。此方式只能调用异步方法。
(使用async和await定义异步方法不会创建新线程,所以使用Thread.Sleep(3000)主线程也会阻塞卡死)
(由于不是开始新线程,所以在方法内页面的所有控件都可以直接访问)
而async await Task.Run是一个真实的异步模式,此方式实质就是开启一个新的托管的线程。并且此方式可以调用同步方法。
(使用await Task.Run定义异步方法会创建新线程,所以使用Thread.Sleep(3000)不影响主线程)
(不考虑资源消耗的情况下,使用await Task.Run貌似是个更好的选择)(当然开启新线程会消耗更多的资源)
(由于是开启新新线程,所以在await Task.Run方法体中就不可以直接调用页面内控件了,需要使用this.Dispatcher.BeginInvoke调用控件)
task.run 看来就是以前的开一个线程,类似于thread.start
不是必要与await一起使用的
可以单独使用
加await就是相当于异步同步操作
task才是核心
await和async都是怎么调用的定义
关于线程中更新控件值原则: 如果线程里执行的程序如果一直要更新控件值,那么线程中需要调用控件并且修改值(比如进度条),如果控件只需要线程运行完成后的结果值,那么不应该在线程中调用控件,只需要在线程结束后获取的值在线程外主线程直接更新控件值就可以了(当然也不是绝对,比如更新的数据量大,那么还是可能造成主线程阻塞,此时在线程内部更新控件值也是个好选择)
lamada表达式 这种 省了一个委托和传参
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | public partial class YiBuTest : Window { public YiBuTest() { InitializeComponent(); } private void MainWindow_Loaded( object sender, RoutedEventArgs e) { } private async void btnClick_Click( object sender, EventArgs e) { // 这里可以做一些不依赖回复的操作 richTextBox1.Text += "\r\n等待服务器回复中.................\n" ; //long length = await AccessWebAsync(); long length = await GetAwaitRunString( "参数" ); richTextBox1.Text += String.Format( "\n 回复成功,字节长度为: {0}.\r\n" , length); txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString(); } #region await调用异步方法(使用async和await定义异步方法不会创建新线程,所以使用Thread.Sleep(3000)主线程也会阻塞卡死)(由于不是开始新线程,所以在方法内页面的所有控件都可以直接访问) // 使用C# 5.0中提供的async 和await关键字来定义异步方法 // 从代码中可以看出C#5.0 中定义异步方法就像定义同步方法一样简单。 // 使用async和await定义异步方法不会创建新线程, // 它运行在现有线程上执行多个任务. // 此时不知道大家有没有一个疑问的?在现有线程上(即UI线程上)运行一个耗时的操作时, // 为什么不会堵塞UI线程的呢? // 这个问题的答案就是 当编译器看到await关键字时,线程会 private async Task< long > AccessWebAsync() { MemoryStream content = new MemoryStream(); // 对MSDN发起一个Web请求 HttpWebRequest webRequest = WebRequest.Create( "https://docs.microsoft.com/zh-cn/" ) as HttpWebRequest; if (webRequest != null ) { // 返回回复结果 using (WebResponse response = await webRequest.GetResponseAsync()) { using (Stream responseStream = response.GetResponseStream()) { await responseStream.CopyToAsync(content); } } } txbAsynMethodID.Text = Thread.CurrentThread.ManagedThreadId.ToString(); return content.Length; } #endregion #region await调用同步方法await Task.Run(使用await Task.Run定义异步方法会创建新线程,所以使用Thread.Sleep(3000)不影响主线程)(不考虑资源消耗的情况下,使用await Task.Run貌似是个更好的选择)(当然开启新线程会消耗更多的资源) //(由于是开启新新线程,所以在await Task.Run方法体中就不可以直接调用页面内控件了) private async Task< long > GetAwaitRunString( string str) { var task = await Task.Run< long >(() => { return tongbufangfa(str); }); return task; } private long tongbufangfa( string str) { //线程停顿3秒 Thread.Sleep(3000); MemoryStream content = new MemoryStream(); // 对MSDN发起一个Web请求 HttpWebRequest webRequest = WebRequest.Create( "https://docs.microsoft.com/zh-cn/" ) as HttpWebRequest; if (webRequest != null ) { // 返回回复结果 using (WebResponse response = webRequest.GetResponse()) { using (Stream responseStream = response.GetResponseStream()) { responseStream.CopyTo(content); } } } return content.Length; } #endregion } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2011-08-18 IE8的“文件下载的自动提示”
2011-08-18 win7 家庭网络 工作网络 公用网络
2008-08-18 UNION 和UNION ALL 的区别
2008-08-18 弹出div后其它不能操作(小技巧)
2007-08-18 ASP.NET中实现Flash与.NET的紧密集成(转,没看,有空研究一下)
2007-08-18 ASP.NET页面打印技术的总结(转)
2007-08-18 ASP.NET中常用的26个优化性能方法(转)