本文共 3820 字,大约阅读时间需要 12 分钟。
为什么需要异步,异步对可能起阻止作用的活动(例如,应用程序访问 Web 时)至关重要。 对 Web 资源的访问有时很慢或会延迟。 如果此类活动在同步过程中受阻,则整个应用程序必须等待。 在异步过程中,应用程序可继续执行不依赖 Web 资源的其他工作,直至潜在阻止任务完成。
本节将一步一步带领大家理解async和await。
期间会有
,,,,,以及线程中常涉及到的和,以及微软提供的
推荐先看后顶,学的更快!
Hello World
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
原理
其实不管是Task,ThreadPool,本质最终都是Thread。只不过微软帮我们在简化线程控制的复杂度。
线程池是CLR中事先定义好的一些线程。Task取的线程池,只不过在语法上,可以非常方便取返回值。
异步会提高程序的运行速度吗
多线程会提高程序的效率,不会提高运行速度。
这就好比这一个任务让前台花1个小时。前台完成10分钟的时候
打电话给经理,让他安排一个人来干30分钟(new Thread()),他干剩下的20分钟。(创建线程,需要时间,内存资源)
或者从旁边空闲的同事中(ThreadPool 或 Task),拉一个人过来干30分钟。他干剩下的20分钟。(需要的时间少,资源本来就存在)
从上看出,异步会让一份任务时间变长。资源消耗更多。但是可以让前台(UI线程)空闲下来,听从领导(用户)指挥。
async和await只是一个标记
首先看个Demo,
1 2 3 4 5 6 7 8 9 10 11 |
|
发现执行结果是:
这个很正常。但是我们希望先执行主线程完成标记,不改动主线程和Task的任务情况下,如何处理?
使用await和async
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
1.凡是使用await关键字的方法,都必须打上async标记。
2.async表示方法内有异步方法,调用async方法,会立刻另起线程执行。
3.await只是显示等待线程结束。await表示等待异步方法执行完,并取返回值。
MVC中的异步Action
既然多线程不能提高运行速度,而且每次请求Asp.net程序都是发起一个新的线程,为什么还要用多线程让其“降速”?
为了提高网站的吞吐量。
在MVC中,如果采用异步Action,则会像下面情况执行。
1.请求到达IIS,IIS应用程序池分配一个worker线程用来响应请求。
2.worker线程,执行异步操作,调用CLR线程池线程处理。
3.释放worker线程,响应其他请求。
4.异步操作执行完,w3wp(应用程序池进程)再次分配一个worker线程继续响应。
上述使用场景中,会获取两次worker 线程,这两次获取的线程可能相同,也可能会不同。如果有比较耗时的任务,非常建议把同步请求转换为异步。
线程安全和信号量
先举个线程不安全的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
上面的执行结果,这就是线程不安全。(多线程访问同一段代码 产生不确定结果。)
如何解决,涉及到线程锁的概念。线程锁会让多线程访问的时候,一次只允许一个线程进入。
线程锁例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
信号量
线程锁的技术使一块代码只能一个线程进入。信号量的存在,则是让同一块代码指定多个线程进入。
信号量(SemaphoreSlim)例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
上面执行结果
从 .NET Framework 4.5 和 Windows 运行时中列出的 API 包含支持异步编程的方法。
应用程序区域 | 包含异步方法的受支持的 API |
---|---|
Web 访问 | , |
使用文件 | 、、、 |
使用图像 | 、、 |
WCF 编程 |
转载地址:https://credream.blog.csdn.net/article/details/89399258 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!