探尋ASP.NET MVC鮮為人知的奧秘(2):與Entity Framework配合,讓非同步貫穿始終

來源:互聯網
上載者:User

標籤:style   class   blog   code   http   ext   

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擴充方法,增加了非同步載入的功能。

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

 

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

 

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

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

如果您覺得這篇文章真扯淡,那麼你又給我刷了個訪問量!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.