ajax请求是宏任务还是微任务_ASP.NET Web API基础(04)---异步编程和跨域请求 - 高原秃鹫...
异步编程
.1 线程回顾
说到异步编程,离不开多线程。在前面的课程中我们学习过多线程。回顾一下我们之前的例子。
public static void DoWork() { (1000); ("线程中执行任务……"); } static void Main(string[] args) { Thread thread = new Thread(DoWork); (); ("主程序继续执行!"); (); } |
允许结果如下。
多线程的意义在于一个应用程序中,有多个执行部分可以同时执行;对于比较耗时的操作(例如io,数据库操作),或者等待响应(如WCF通信)的操作,可以单独开启后台线程来执行,这样主线程就不会阻塞,可以继续往下执行;等到后台线程执行完毕,再通知主线程,然后做出对应操作!
试想一下,如果有大量的任务需要处理,例如网站后台对于HTTP请求的处理,那是不是要对每一个请求创建一个后台线程呢?显然不合适,这会占用大量内存,而且频繁地创建的过程也会严重影响速度,那怎么办呢?线程池就是为了解决这一问题,把创建的线程存起来,形成一个线程池(里面有多个线程),当要处理任务时,若线程池中有空闲线程(前一个任务执行完成后,线程不会被回收,会被设置为空闲状态),则直接调用线程池中的线程执行。
下面的代码就是从线程池中创建线程并执行。
for (int i = 0; i < 10; i++) { (m => { ("线程ID:"+ ()); }); } (); |
运行结果如下。
可以看到,虽然执行了10次,但并没有创建10个线程。
.2 Task 和 Task<TResult>
Task是.加入的,跟线程池ThreadPool的功能类似,用Task开启新任务时,会从线程池中调用线程,而Thread每次实例化都会创建一个新的线程。
("主线程启动"); Task task = (() => { (1500); ("task启动"); }); (); ("主线程结束"); |
运行结果如下。
开启新任务的方法:()或者(),开启的是后台线程。
要在主线程中等待后台线程执行完毕,可以使用Wait方法(会以同步的方式来执行)。不用Wait则会以异步的方式来执行。
Task<TResult>就是有返回值的Task,TResult就是返回值类型。
("主线程开始"); //返回值类型为string Task<string> task = Task<string>.Run(() => { (2000); return "任务返回的结果"; }); //会等到task执行完毕才会输出; (); ("主线程结束"); |
运行结果如下。
通过可以取到返回值,若取值的时候,后台线程还没执行完,则会等待其执行完毕。
.3 async/await
C# 5.0中引入了async 和 await。这两个关键字可以让你更方便的写出异步代码。用法如下。
static Task<string> GetString() { //("GetString方法开始执行") return Task<string>.Run(() => { (2000); return "GetString的返回值"; }); } static async Task<int> GetStrLengthAsync() { ("GetStrLengthAsync方法开始执行"); //此处返回的<string>中的字符串类型,而不是Task<string> string str = await GetString(); ("GetStrLengthAsync方法执行结束"); return str.Length; } static void Main(string[] args) { ("-------主线程启动-------"); Task<int> task = GetStrLengthAsync(); ("主线程继续执行"); ("Task返回的值" + ); ("-------主线程结束-------"); (); } |
运行结果如下。
可以看出来,main函数调用GetStrLengthAsync方法后,在await之前,都是同步执行的,直到遇到await关键字,main函数才返回继续执行。
上面提到可以让主线程等待后台线程执行完毕,await和wait类似,同样是等待,等待Task<string>.Run()开始的后台线程执行完毕,不同的是await不会阻塞主线程,只会让GetStrLengthAsync方法暂停执行。
async用来修饰方法,表明这个方法是异步的,声明的方法的返回类型必须为:void,Task或Task<TResult>。
await必须用来修饰Task或Task<TResult>,而且只能出现在已经用async关键字修饰的异步方法中。通常情况下,async/await成对出现才有意义。
所有Task<TResult>的返回值都是直接用获取,这样如果后台任务没有执行完毕的话,主线程会等待其执行完毕,这样的话是不是就和同步一样了?看上去一样,但其实await的时候并不会造成线程的阻塞。我们看下面的示例。
static void Main(string[] args) { ("主线程开始"); Task<string> task = Task<string>.Run(() => { (2000); return "任务返回的结果"; }); //会等到任务执行完之后执行 ().OnCompleted(() => { (); }); ("主线程结束"); (); } |
OnCompleted中的代码会在任务执行完成之后执行,运行结果如下。
.4 在ASP.NET Web API中使用async/await
当在数据库中执行查询时,异步查询可避免阻止线程。异步操作还可以增加 Web 应用程序的吞吐量,可以在数据库操作完成时释放线程去处理其他请求。
- 异步查询
public async Task<IHttpActionResult> GetStudentAsync() { Student student = null; using (var context = new SchoolDBEntities()) { //注意await和FirstOrDefaultAsync student = await ((s => s.StudentID == 1).FirstOrDefaultAsync<Student>()); } return Json(student); } |
- 异步保存
public async Task<IHttpActionResult> Put(Student stu) { using (var context = new SchoolDBEntities()) { (stu).State = int x = await (()); return Ok("保存完成"); } } |
在 扩展类中,提供了一系列异步方法,如:FirstOrDefaultAsync()、ToListAsync()、ToArrayAsync()、SingleAsync()等。另外还有DbContext对象的SaveChangesAsync()方法。
跨域请求
.1 什么是跨域
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。
同源策略限制了一下行为:
l Cookie、LocalStorage 和 IndexDB 无法读取
l DOM 和 JS 对象无法获取
l Ajax请求发送不出去
2. 常见的跨域场景
所谓的同源是指,域名、协议、端口均为相同。
URL |
说明 |
是否允许 |
http://www.aoxiang.cn/index.html http://www. aoxiang.cn/server.php |
非跨域 |
允许 |
http://www. aoxiang.cn/index.html http://www.neal.cn/server.php |
跨域,主域不同 |
不允许 |
http://abc. aoxiang.cn/index.html http://def. aoxiang.cn/server.php |
跨域,子域名不同 |
不允许 |
http://www. aoxiang.cn:8080/index.html http://www. aoxiang.cn/server.php |
跨域,端口不同 |
不允许 |
https://www. aoxiang.cn/index.html http://www. aoxiang.cn/server.php |
跨域,协议不同 |
不允许 |
当发生跨域时,经常会引发如下形式的异常。
.2 跨域问题解决方案
1. Mvc和WebApi通用的模式
该模式是MVC和WebApi通用的一种处理模式,简单便捷,不需要额外添加多余的程序集,只需要在WebConfig中进行配置一下即可。
同时缺点也比较明显,那就是只能全局配置,配置完后,所有的控制器下的方法都支持跨域了。
代码配置如下,在 <节点的最顶部添加如下代码:
< |
其中,
l Access-Control-Allow-Origin :代表允许请求的地址,如:" http://localhost:2131, http://localhost:2133" 多个地址之间用逗号隔开,* 代表运行所有
l Access-Control-Allow-headers: 代表允许的表头
l Access-Control-Allow-method: 代表允许请求的方法。如:"GET,PUT,POST,DELETE"
2. WebApi特有的处理方式
首先通过Nuget添加【】程序集。该程序集中的核心方法:
EnableCorsAttribute(string origins, string headers, string methods)
其参数分别表示:
origins代表允许请求的地址:" http://localhost:2131, http://localhost:2133" 多个地址之间用逗号隔开。
headers代表允许的表头。
method代表允许请求方法:"GET,PUT,POST,DELETE"
* 代表允许所有。
该模式和上述通用的模式相比较, 最大的好处就是比较灵活,既可以作用于全局,也可以特性的形式作用于Controller,或者直接作用于Action。
1. 作用于全局
在WebApiConfig类中的Register方法中添加:(new EnableCorsAttribute("*", "*", "*"));
2. 作用于Controller
(1). 在WebApiConfig类中的Register方法中添加:();
(2). 在FifthController控制器上添加特性:[EnableCors("*", "*", "*")]
3. 作用于Action
(1). 在WebApiConfig类中的Register方法中添加:();
(2). 在GetUserName2方法上添加特性:[EnableCors("*", "*", "*")]
部分代码如下所示:
ajax请求是宏任务还是微任务_ASP.NET Web API基础(04)---异步编程和跨域请求 - 高原秃鹫...相关推荐
- Ajax跨域请求解决方案——jsonp
转自:http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html 1.一个众所周知的问题,Ajax直接请求普通 ...
- $.ajax跨域请求数据的解决方案
最近一直在搞公众号前台开发,遇到了ajax跨域请求的问题,像地区的省-市-县三级联动.汽车品牌-车系-车款的三级联动查询等都需要调用外部接口(其他工程项目的接口)完成.下面就分享一下个人解决跨域请求的 ...
- js跨域请求方式 ---- JSONP原理解析
这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的X ...
- juery的跨域请求2
时间过得好快,又被拉回js战场时, 跨域问题这个伤疤又开疼了. 好在,有jquery帮忙,跨域问题似乎没那么难缠了.这次也借此机会对跨域问题来给刨根问底,结合实际的开发项目,查阅了相关资料,算是解决了 ...
- java angularjs 跨域访问_AngularJS实现跨域请求
跨域,前端开发中常常遇到的问题.AngularJS实现跨域方式类似于Ajax.使用CORS机制. 以下阐述一下AngularJS中使用$http实现跨域请求数据. AngularJS XMLHttpR ...
- 简单跨域请求和带预检的跨域请求
受浏览器的同源策略限制,JavaSript只能请求本域内的资源.跨域资源共享(Cross-Origin Resource Sharing, CORS)是为解决Ajax技术难实现跨域问题而提出的一个规范 ...
- Nginx配置跨域请求 Access-Control-Allow-Origin *
Nginx配置跨域请求 Access-Control-Allow-Origin * 当出现403跨域错误的时候 No 'Access-Control-Allow-Origin' header is p ...
- Thinkphp5.1允许uni-app的H5跨域请求接口解决方法
Thinkphp5.1允许uni-app的H5跨域请求接口解决方法 参考文章: (1)Thinkphp5.1允许uni-app的H5跨域请求接口解决方法 (2)https://www.cnblogs. ...
- 跨域请求,关于后端session会话丢失的解决办法
目前使用前后端分离的模式开发,后端提供跨域接口.前端jsonp调用,绑定数据,但是在该站点下有个人中心模块存在的情况下,服务端的session会话会被跨域请求覆盖改掉 大家都知道tomcat使用coo ...
最新文章
- 《愤怒的小鸟》对移动互联网经营的启示
- [python] 溜了,溜了,七牛云图片资源批量下载 自建图床服务器
- 用Scikit-learn和TensorFlow进行机器学习(二)
- 事务的隔离级别演示-避免脏读,演示不可重复读发生
- [AC自动机][dfs] 洛谷 P2444 病毒
- Django之管理权限
- oracle 创建clob类型字段的索引,LOB字段相关概念(自动创建LOB索引段和重建索引方法)...
- mybatis分页插件_MyBatis 分页插件 5.2.0 发布
- 删除部分mysql日志_正确删除MYSQl日志方法
- WordPress目录解析
- 数学基础(9)--MATLAB 数据拟合 SSE,MSE,RMSE,R-square
- 那些年,我们一起追过的seo培训!
- ps怎么转为html和css,一个登录界面的PS设计和HTML/CSS实现
- 计算机桌面备份在哪里,电脑备份文件在哪里
- t5_Sophisticated Algorithmic Strategies(MeanReversion+APO+StdDev_TrendFollowing+APO)_StatArb统计套利_PnL
- [ABAP] PBOM历史版本函数展开 CSAP_MAT_BOM_READ
- HarmonyOS实战—实现相亲APP
- Socket详解-socket建立
- 郊区春游(NC16122)状压dp
- 关于Deepin商店没有应用的解决办法
热门文章
- 笔记本电脑搜不到wifi怎么办?
- WordPress XMLRPC安全漏洞
- 苹果系统 如何快速访问服务器,mac下的finder怎么使用技巧 苹果系统如何快速打开Finder...
- [心得]写文章不是求评论,而是自我总结提高
- 数理统计基础-相关系数
- 超详细!Win10(UEFI启动)安装Ubuntu18.04双系统
- YOLOv5、CNN、SVM实现车牌检测
- linux 追加多行文件,linux每行追加内容
- python numpy 图片 pad 参数详解
- ueditor编辑器上传图片的显示问题