最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来。

十年河东十年河西,莫欺少年穷

学无止境,精益求精  

为什么使用异步操作/线程池

ASP.NET MVC 中为什么需要使用异步呢,IIS有一个线程池来处理用户的请求,当一个新的请求过来时,将调度池中的线程以处理该请求,然而,但并发量很高的情况下,池中的线程已经不能够满足这么多的请求时候,池中的每一个线程都处于忙的状态则在处理请求时将阻塞处理请求的线程,并且该线程不能对另一个请求提供服务,如果请求队列已满,则 Web 服务器会拒绝请求并处于 HTTP 503繁忙状态。如果是处理一些高延迟,例如网络操作,这样的线程大多数只是等待状态大部分时间是不做任何事情的,这样的线程就可以使用异步编程更好的充分利用。

异步处理

例如:如果某个请求生成一个需要两秒钟来完成的网络调用,则该请求无论是同步执行还是异步执行都需要两秒钟。 但是,在异步调用的过程中,服务器在等待第一个请求完成的过程中不会阻塞对其他请求的响应。 因此,当有许多请求调用长时间运行的操作时,异步请求可以防止出现请求排队的情况。在.NET 4.5中最大线程池为 5000 .NET 4.5中也增加了 await与async关键字来简化异步编程。

同步还是异步(摘录MSDN)

通常,在满足以下条件时使用同步管线:

  • 操作很简单或运行时间很短。

  • 简单性比效率更重要。

  • 此操作主要是 CPU 操作而不是包含大量的磁盘或网络开销的操作。 对 CPU 绑定操作使用异步操作方法未提供任何好处并且还导致更多的开销。

通常,在满足以下条件时使用异步管线:

  • 操作是网络绑定的或 I/O 绑定的而不是 CPU 绑定的。

  • 测试显示阻塞操作对于网站性能是一个瓶颈,并且通过对这些阻塞调用使用异步操作方法,IIS 可对更多的请求提供服务。

  • 并行性比代码的简单性更重要。

  • 您希望提供一种可让用户取消长时间运行的请求的机制。

ASP.NET MVC 中使用异步控制器

#region 1、异步请求

        [AsyncTimeout()]
public async Task<ActionResult> Index()
{
var data = await GetPageTaskAsync("http://163.com");
return data;
} public async Task<ActionResult> GetPageTaskAsync(string url)
{
try
{
using (var client = new HttpClient())
{
await Task.Delay();
var fetchTextTask = client.GetStringAsync(url);
return Json(new { fetchText = await fetchTextTask,error="NO" },JsonRequestBehavior.AllowGet);
}
}
catch (WebException ex)
{ throw ex;
}
} #endregion

下面以EF为例进行说明:

代码中高亮部分显示了异步方法和同步方法的不同之处:

        public async Task<ActionResult> Index()
{
var departments = db.Departments.Include(d => d.Administrator);
return View(await departments.ToListAsync());
}

我们应用了四个更改来启用实体框架数据库执行异步查询:

  • 该方法使用了async关键字,它告诉编译器生成回调方法体的部分,并自动创建Task<ActionResult>返回对象。
  • 返回类型从ActionResult更改为Task<ActionResult>。Task<T>类型表示正在进行的任务具有类型为T的结果。
  • await关键字被应用到web服务调用。当编译器看到有此关键字时,在后台将该方法分为两个部分。第一部分结束于异步操作启动,第二部分被放入一个操作完成时的回调方法。
  • 调用了ToList扩展方法的异步版本。

为什么只修改departments.ToList语句而不是departments= db.Departments语句?原因是只有被发送的数据库执行的查询或语句才能够使用异步执行。departments=db.Departments语句设置了一个查询,但直到调用ToList方法时该查询都不会执行。因此,只有ToList方法是异步执行的。

在Details方法和Httpget的Edit和Delete方法中,Find方法是导致查询被发送到数据库进行检索的方法,所以该方法是可以异步执行的。

public async Task<ActionResult> Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Department department = await db.Departments.FindAsync(id);
if (department == null)
{
return HttpNotFound();
}
return View(department);
}

在Create,HttpPost的Edit和DeleteConfirmed方法中,是SaveChanges方法导致命令执行,而像db.Department.Add(department)方法只是导致实体在内存中的修改。

public async Task<ActionResult> Create([Bind(Include="DepartmentID,Name,Budget,StartDate,InstructorID")] Department department)
{
if (ModelState.IsValid)
{
db.Departments.Add(department);
await db.SaveChangesAsync();
return RedirectToAction("Index");
} ViewBag.InstructorID = new SelectList(db.Instructors, "ID", "LastName", department.InstructorID);
return View(department);
}

程序正常地运行,就跟其他的控制器一样。但在此控制器中,所有SQL查询都是异步执行的。

当您在实体框架中使用异步编程要注意的一些事情:

  • 异步代码不是线程安全的。换言之,不要使用同一个上下文实例以并行方式来执行多个操作。
  • 如果你想要利用异步代码的性能优势,请确保您正在使用的所有库软件包(例如分页),在包中进行的数据库查询等任何实体框架方法也使用异步执行。

@陈卧龙的博客

ASP.NET MVC EF 中使用异步控制器的更多相关文章

  1. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  2. ASP.NET MVC 学习笔记-6.异步控制器

    1)         异步控制器的由来 对于IIS,它维护了一个.NET线程池来处理客户端请求,这个线程池称为工作线程池,其中的线程称为工作线程.当IIS接收到一个请求时,需要从工作线程池中唤醒一个工 ...

  3. ASP.NET MVC中使用异步控制器

    线程池 一直想把项目改写成异步,但是ASP.NETMVC3下写的过于繁琐,.NET 4.5与ASP.NET MVC下代码写起来就比较简单了, MS好像也一直喜欢这样搞,每一个成熟的东西,都要演变好几个 ...

  4. 在 ASP.NET MVC 中使用异步控制器

    线程池 一直想把项目改写成异步,但是ASP.NETMVC3下写的过于繁琐,.NET 4.5与ASP.NET MVC下代码写起来就比较简单了, MS好像也一直喜欢这样搞,每一个成熟的东西,都要演变好几个 ...

  5. 看stackoverflow大牛如何回答何时在ASP.NET中使用异步控制器?

    转载自博客园:http://farb.cnblogs.com/ 今天无意中看到stackoverflow上一个很好的问答,个人觉得很有价值,所以翻译过来和大家共享!希望大家能相互交流. 在ASP.NE ...

  6. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(12)-实现用户异步登录和T4模板

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(12)-实现用户异步登录和T4模板 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建  ...

  7. asp.net MVC 框架中控制器里使用Newtonsoft.Json对前端传过来的字符串进行解析

    下面我用一个实例来和大家分享一下我的经验,asp.net MVC 框架中控制器里使用Newtonsoft.Json对前端传过来的字符串进行解析. using Newtonsoft.Json; usin ...

  8. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(24)-权限组的设计和实现(附源码)(终结)

    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    ...

  9. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(23)-设置角色遗留问题和为权限设置角色以及EasyUI Tabs的使用

    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    ...

随机推荐

  1. PPM格式解析

    PPM格式其实就是RGB数据加上一个简单的文件头, 文件头部表示了图像的宽度和高度以及最大的RGB值. 文件头+rgb数据: P6\n width height\n 255\n rgbrgb... 其 ...

  2. 前台处理json字符串的几种方法(转)

    原文地址http://www.css88.com/archives/3919 比如我有两个变量,我要将a转换成字符串,将b转换成JSON对象: var a={"name":&quo ...

  3. Linux crontab 命令格式与详细例子

    基本格式 :* * * * * command分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示第2列表示小时1-23(0表示0点)第3列表示日期1-31第4列表示月份1-1 ...

  4. python函数

    一.函数: 创建函数:使用def语句 举例:定义一个返回斐波那楔数列列表的函数 def fibs(num): result = [0,1] for i in range(num-2): result. ...

  5. cesiumjs开发实践之坐标转换

    cesium中常用的坐标有两种WGS84地理坐标系和笛卡尔空间坐标系.我们平时常用的以经纬度来指明一个地点就是用的WGS84坐标,笛卡尔空间坐标系常用来做一些空间位置变换如平移旋转缩放等等. 笛卡尔空 ...

  6. 【python+mysql】在python中调用mysql出问题 ImportError: No module named MySQLdb.constants

    遇到如下异常: File "C:\Users\Neil\PycharmProjects\ScrapyDouban\book\book\database.py", line 4, i ...

  7. SQL SERVER数据类型与C#数据类型对照表

      SQL SERVER类型   C#类型 精确数字 bigint 从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数 ...

  8. Git 恢复某个文件指定版本

    1. git reflog  找到comit id 2. git reset edf92f a.txt 3. git commit -m "ssss" 4. git checkou ...

  9. mmysql-最大链接数和最大并发数的区别

    关于连接数和并发数的设置(针对Innodb引擎) 对于机器本身来说,进程数是说机器正在运行的进程数量,调出任务管理器就可以看到.连接数是指进程接收和发送数据的连接ip的数量.并发数是指进程同时发送数据 ...

  10. CentOS 6.6 安装 Node.js

    node.js 的 GitHub 地址是:https://github.com/nodejs/node 官网源码包下载地址时:https://nodejs.org/en/download/ ① 获取并 ...