探寻ASP.NET MVC鲜为人知的奥秘(2):与Entity Framework配合,让异步贯穿始终

Why

在应用程序,尤其是互联网应用程序中,性能一直是很多大型网站的困扰,由于Web2.0时代的到来,人们更多的把应用程序从C/S结构迁移到B/S结构,这样会带来客户端轻量,部署、试试方便快捷等优势,但是万事万物都有他的两面性,这样的发展趋势同时也带来了其他方便的不好影响,其中很重要的一项就是系统对服务器的性能要求提高,随着用户量增多和系统功能的增加,服务器性能渐渐成了短板。

这种性能的影响,可以从诸多方面进行优化,比如使用负载均衡的服务器,建立服务器集群等方式,但是这是从硬件配置方面的优化,而在软件开发方面,同样也可以做很多性能方面的优化。

我们都知道,微软的IIS服务器中每个线程数量是有限的,在以往的ASP.NET MVC应用程序中,当一个请求到达服务器,IIS从线程池中创建一个线程开始执行调用,当执行完所有的操作将请求返回,再释放线程,也就是说整个调用过程中,线程是一只持有的。

可如果程序访问人数增加,线程就成了一种稀缺的资源,如果在一次请求中,需要访问远程数据库、或者进行大的IO处理,这是请求很可能就会长期的持有一个线程,而当用户量大这种长期请求多的时候,线程池就会迅速的被占满,请求进入等待队列,而且等待队列也是有最大长度的,同时还可能将请求超时返回给浏览器端。

所以,我们就会想需要一种异步的方式来执行请求,当遇到长请求的时候,将请求从IIS线程交由后台线程处理,释放当前线程,处理完成后,再从线程池中选择线程继续进行请求的其它处理。

How

在ASP.NET MVC3种,已经提供了AsyncController,可以创建异步的控制器,可那时候需要用到Async和Completed方法对的模式来处理,而现在,我们不需要单独去实现继承自AsyncController的类,只需要在原有Action方法上加上特定的关键字和返回类型,就可以创建异步的控制器。

而且,在Entity Framework6中,同样实现了对数据的异步查询和保存的功能,这就使得我们在应用程序整个过程中,都可以以异步的方式处理逻辑。

Let’s  do   it

示例使用VS2013创建一个ASP.NET MVC5项目”AsyncExample“(不纠结于设计原则,注意重点)

在Models文件夹中添加一个用户类:

namespace AsyncExample.Models
{
    public class User
    {
        [Key]
        public int Id { get; set; }
        public string IdentityToken { get; set; }
        public string Name { get; set; }
    }
}

给项目添加Entity Framework的引用

PM> install-package entityframework

创建DbContext子类AsyncDbContext类:

namespace AsyncExample.Models
{
    public class AsyncDbContext:DbContext
    {
        public DbSet<User> Users { get; set; }


        public AsyncDbContext()
            : base("name=DefaultConnection")
        { 
        
        }
    }
}

更新Web.config,添加数据库连接串。

开启Entity framework的Migrations功能:

PM> enable-migrations

BTW:在新版本的Entity Framework中,已经可以使用自动迁移,不需要为每一次的模型变更手动的去升级数据库结构,打开的方法很简单:

打开Migrations文件夹下的Configuration.cs文件,在Configuration默认构造函数中可以看到一个AutomaticMigrationsEnabled属性被设置为False,改成True就可以自动迁移了,颤抖吧

数据库更新完之后,来创建一个控制器:

using System.Data.Entity;

namespace AsyncExample.Controllers
{
    public class UserController : Controller
    {
        AsyncDbContext context = new AsyncDbContext();


        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public async Task<ActionResult> Create(User user)
        {
            context.Users.Add(user);
            await context.SaveChangesAsync();
            return RedirectToAction("List");
        }

        public async Task<ActionResult> List()
        {
            return View(await context.Users.ToListAsync());
        }
    }
}

可以看到在Create和List两个方法中,都使用了async和aswait创建了两个异步的方法,我们也只直接继承了Controller,因为现在的同步异步的功能都放在了这个类里,同时我们需要引入Systen.Data.Entity这个命名空间,其中包含了对IQueryable类型的ToListAsync扩展方法,增加了异步加载的功能。

最终呈现效果,摆图占地:

这篇就到这里了,其实这一系列的下一篇还没确定要写什么内容,希望博友基友好朋友们给点意见把。

如果您觉得这篇文章对您有用,劳烦给个赞!

如果您觉得这篇文章可能对别人游泳,劳烦您推荐一个!

如果您觉得这篇文章真扯淡,那么你又给我刷了个访问量!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏瓜大三哥

Auraro UFC(用户流量控制)

UFC 接口是在启用UFC 生成IPCORE 时创建的。UFCs_axi_ufc_tx_tvalid 和TX 侧的s_axi_ufc_tx_tready 端口启...

19030
来自专栏同步博客

Redis应用----消息传递

  消息传递这一应用广泛存在于各个网站中,这个功能也是一个网站必不可少的。常见的消息传递应用有,新浪微博中的@我呀、给你评论然后的提示呀、赞赞赞提示、私信呀、甚...

18920
来自专栏Golang语言社区

从websocket看go的应用

Go是互联网时代的通用编程语言。这样它就和命令行时代的C语言、图示界面时代的C++、以及互联网早期的Java语言等有不同的侧重。它强调保持自身的精巧和独立,从而...

43280
来自专栏CSDN技术头条

如何用 Redis 实现延时任务?

延时任务,顾名思义,就是延迟一段时间后才执行的任务。延时任务的使用还是很广泛的。关于延时任务的实现方式,我知道的就不少 3 种,今天就讲下如何用 redis 实...

39510
来自专栏大内老A

ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的。如果我们将最终处理HTTP请求的组件称为HttpHandler,...

13000
来自专栏北京马哥教育

图解OS和Linux的基础知识

“试着尽量用图示来表示个人对内容的理解,不足之处,还望不吝指教。” 一. CPU 1. cpu与指令集 CPU分为运算器和控制器 CPU指令 特权指令 拥有管...

31130
来自专栏大内老A

ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的。如果我们将最终处理HTTP请求的组件称为HttpHandler,...

39250
来自专栏美团技术团队

缓存那些事

前言 一般而言,现在互联网应用(网站或App)的整体流程,可以概括如图1所示,用户请求从界面(浏览器或App界面)到网络转发、应用服务再到存储(数据库或文件系统...

76240
来自专栏owent

protobuf-net的动态Message实现

这本来是个早就可以写的分享。因为代码几周前就迁移并准备好了。而且这也是之前项目的工具,因为可以抽离出来通用化所以单独整理出来。

14310
来自专栏Golang语言社区

Golang学习--GroupCache的使用

groupcache 是 Brad Fitzpatrick 最新的作品,目标在于取代一部分memcached的功能。以官方的说明是:groupcache ...

60590

扫码关注云+社区

领取腾讯云代金券