探尋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擴展方法,增加了異步加載的功能。

最終呈現效果,擺圖占地:

 QQ截圖20140613150829 QQ截圖20140613150943

這篇就到這里了,其實這一系列的下一篇還沒確定要寫什么內容,希望博友基友好朋友們給點意見把。

 

如果您覺得這篇文章對您有用,勞煩給個贊!

如果您覺得這篇文章可能對別人游泳,勞煩您推薦一個!

如果您覺得這篇文章真扯淡,那么你又給我刷了個訪問量!X@8}U9MLE}EBUE273)]9PGF


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM