在MVC中使用async和await的说明
2013-09-22 23:24
447 查看
首先,在mvc中如果要用纯异步请不要使用async和await,可以直接使用Task.Run。
其次,在mvc中使用async和await可以让系统开新线程处理Task的代码,同时不必等Task执行结束,就可以同时运行Task之后的代码,加快效率。
要注意的是:如果使用async和await,系统虽然可以同时处理多个事务,但客户端(浏览器)不会有响应,依然要等到所有代码全部执行完毕(包括异步的代码)才能正常响应。
实际工作中,async和await我们可以用于类似用户上传头像、上传照片这种的耗时较长的功能中,我们可以在边上传照片时边处理数据库的其他事务。
而纯异步则多用于时间较长,而无需结果实时看反馈给用户的操作,例如:管理在后台备份数据库、清理垃圾文件等。
如果async和await的异步方法是有返回值的,而且主方法中又要使用这个返回值,那么将不会实现多个异步方法同时执行,要等异步结果后才继续执行,相当于异步并未起到多程序同时处理事务的目的。这仅是对于Web或控制台程序而言的,如果对于Winform则有大大的不同,因为Winform如果使用异步时界面是可以响应的。
Web中异步更多的是用来实现大量IO操作,或大量调用WCF、WebService时使用。
所以,在Mvc这种Web界面中使用async和await异步的实际意义就不是很大了,因为界面总是没有响应的,而且也无法实现多线程同时工作。
有需要请看这篇:http://www.dozer.cc/2012/03/async-and-await-in-web-application/
[b][b]async的作用是异步执行,await的作用是等待执行结果(会卡住异步方法中await以下的代码[b],但不会卡死主线程)。
[/b][/b][/b]
[b][b][b]async一般最终都需要一个async void方法来进行最高层的调用。比如:[/b][/b][/b]private async void Sync_Button_Click(object sender, RoutedEventArgs e),C#中也提供了大量的可设置async的系统方法和事件。
Test函数就用最简单的方法使用了这两个关键字,执行这段代码,首先输出“Main”,然后3秒钟后会输出“1”。
也可以使用:
使用async异步编程时,请注意如下事项:
async void函数只能在UI Event回调中使用。
async void函数中一定要用try-catch捕获所有异常,否则会很容易导致程序崩溃。
async void类型的lambda表达式非常隐蔽,并且容易在无意中编写出来,尤其需要注意。
不要忽视CS4014告警,更不要为了消除CS4014告警而改用async void函数。
确实无需等待的async Task函数用我前面写的扩展函数IgnorCompletion消除这个告警。
注册TaskScheduler.UnobservedTaskException事件,记录Task中未处理异常信息,方便分析及错误定位。(注意,这个回调里面不能进行耗时操作,具体原因参看前面的老赵的那篇Blog)
其次,在mvc中使用async和await可以让系统开新线程处理Task的代码,同时不必等Task执行结束,就可以同时运行Task之后的代码,加快效率。
要注意的是:如果使用async和await,系统虽然可以同时处理多个事务,但客户端(浏览器)不会有响应,依然要等到所有代码全部执行完毕(包括异步的代码)才能正常响应。
/* * 演示如何利用 .net 4.5 的新特性实现异步操作 * * 什么场景下需要异步操作? * 在因为磁盘io或网络io而导致的任务执行时间长的时候应该使用异步操作,如果任务执行时间长是因为cpu的消耗则应使用同步操作(此时异步操作不会改善任何问题) * 原理是什么? * 在 Web 服务器上,.NET Framework 维护一个用于服务 ASP.NET 请求的线程池(以下把 .NET Framework 维护的用于服务 ASP.NET 请求的线程池称作为“特定线程池”) * 同步操作时,如果特定线程池利用满了,则不会再提供服务 * 异步操作时: * 1、一个请求过来,特定线程池出一个线程处理此请求 * 2、启动一个非特定线程池中的另一个线程处理异步操作,此时处理此请求的线程就会空出来,不会被阻塞,它可以继续处理其它请求 * 3、异步操作执行完毕后,从特定线程池中随便找一个空闲线程返回请求结果 */
实际工作中,async和await我们可以用于类似用户上传头像、上传照片这种的耗时较长的功能中,我们可以在边上传照片时边处理数据库的其他事务。
而纯异步则多用于时间较长,而无需结果实时看反馈给用户的操作,例如:管理在后台备份数据库、清理垃圾文件等。
如果async和await的异步方法是有返回值的,而且主方法中又要使用这个返回值,那么将不会实现多个异步方法同时执行,要等异步结果后才继续执行,相当于异步并未起到多程序同时处理事务的目的。这仅是对于Web或控制台程序而言的,如果对于Winform则有大大的不同,因为Winform如果使用异步时界面是可以响应的。
Web中异步更多的是用来实现大量IO操作,或大量调用WCF、WebService时使用。
所以,在Mvc这种Web界面中使用async和await异步的实际意义就不是很大了,因为界面总是没有响应的,而且也无法实现多线程同时工作。
有需要请看这篇:http://www.dozer.cc/2012/03/async-and-await-in-web-application/
[b][b]async的作用是异步执行,await的作用是等待执行结果(会卡住异步方法中await以下的代码[b],但不会卡死主线程)。
[/b][/b][/b]
[b][b][b]async一般最终都需要一个async void方法来进行最高层的调用。比如:[/b][/b][/b]private async void Sync_Button_Click(object sender, RoutedEventArgs e),C#中也提供了大量的可设置async的系统方法和事件。
class Program { private static async void Test() { Task<int> t = new Task<int>(() => { Thread.Sleep(3000); return 1; }); t.Start(); int tr = await t; Console.WriteLine(tr); } static void Main(string[] args) { Test(); Console.WriteLine("Main"); Console.ReadKey(); } }
Test函数就用最简单的方法使用了这两个关键字,执行这段代码,首先输出“Main”,然后3秒钟后会输出“1”。
也可以使用:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication11 { class Program { static void Main(string[] args) { Test(); Console.WriteLine("Main"); Console.ReadKey(); } private static async void Test() { var t = Task<int>.Run(() => { Thread.Sleep(3000); return 1; }); Console.WriteLine(await t); } } }
使用async异步编程时,请注意如下事项:
async void函数只能在UI Event回调中使用。
async void函数中一定要用try-catch捕获所有异常,否则会很容易导致程序崩溃。
async void类型的lambda表达式非常隐蔽,并且容易在无意中编写出来,尤其需要注意。
不要忽视CS4014告警,更不要为了消除CS4014告警而改用async void函数。
确实无需等待的async Task函数用我前面写的扩展函数IgnorCompletion消除这个告警。
注册TaskScheduler.UnobservedTaskException事件,记录Task中未处理异常信息,方便分析及错误定位。(注意,这个回调里面不能进行耗时操作,具体原因参看前面的老赵的那篇Blog)
private async void Sync_Button_Click(object sender, RoutedEventArgs e) { 2: OutputTextBlock.Text += "開始" + Environment.NewLine; 3: // 這裡會等 getFileContentAsync() 執行完畢後, 再執行貼上結束字串那一行 4: // 因為 Compiler 會再 await 這行下斷點 5: OutputTextBlock.Text += await getFileContentAsync(); 6: OutputTextBlock.Text += "結束" + Environment.NewLine; 7: } 8: 9: private async Task<string> getFileContentAsync() { 10: StorageFolder folder = KnownFolders.DocumentsLibrary; 11: StorageFile file = await folder.GetFileAsync(TESTED_FILE_NAME); 12: var result = await FileIO.ReadTextAsync(file) + Environment.NewLine; 13: return result; 14: }
相关文章推荐
- 在MVC中使用async和await的说明
- MVC 5中Async和await使用
- MVC(七、action 中使用await和async)
- [新手上路] [原创]使用ASP.NET MVC 4 Async Action + jQuery 实现消息通知机制
- [C#] .NET4.0中使用4.5中的 async/await 功能实现异
- .net4.5新特性之异步编程(Async和Await)的使用
- 不要在 ASP.NET 4.5 Beta 的 Page 类事件上直接使用 async 与 await
- 介绍.net 4.5 异步编程核心内容,如何使用Async和Await进行异步编程
- 为什么我们要使用Async、Await关键字
- C# Async与Await的使用
- 如何在.net4.0中使用.net4.5的async/await实现异步
- mvc 关于何时使用 辅助器、分部视图、子动作说明
- 优化JS中的Async/Await 使用
- ASP.NET MVC @helper使用说明
- reactjs 使用异步终级解决方案 async,await实践
- asp.net mvc中在使用async的时候HttpContext为null的问题
- .NET/C# 使用async和await关键字调用异步方法
- async/await - 8.在for循环中正确的使用await
- mvc DevExpress 汉化 使用 说明
- C# Async与Await的使用