亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ASP.NET基于事件的異步模式與異步Action怎么實現

發布時間:2021-12-06 15:48:15 來源:億速云 閱讀:218 作者:iii 欄目:編程語言

本篇內容主要講解“ASP.NET基于事件的異步模式與異步Action怎么實現”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“ASP.NET基于事件的異步模式與異步Action怎么實現”吧!

盡管在ASP.NET MVC 1中是不能直接支持異步Action,但在ASP.NET MVC 2中已經正式支持ASP.NET中的異步請求處理方式,并且通過一種比較易于使用的方式提供給開發人員使用。只可惜,由于語言層面的約束,這種使用方式還是有些不便,而此時便是F#的用武之地了。

基于事件的異步模式

說起.NET中的異步編程模型,.NET程序員最熟悉的應該就是Begin/End方法了。例如在WebRequest類中,便有這樣一對方法:

var request = WebRequest.Create("http://www.51cto.com/");  request.BeginGetResponse(ar => {      var response = request.EndGetResponse(ar);      // use the response object   }, null);

在調用WebRequest對象的BeginGetResponse方法之后,當前調用線程不會被阻塞,而在異步操作完成之后,便會調用一個回調函數(即這里使用Lambda表達式構造的代碼快)進行通知,在這個回調函數中調用EndGetResponse方法便可以得到一個WebResponse對象作為結果。

在這個異步操作中,由于偉大的IOCP,我們可以使用極少數的線程同時發起成千上萬個連接(豪不夸張,我曾經在IIS里進行Comet試驗,同時建立起超過2w個連接進行通信)。不過,事實上在.NET中還有一種基于事件的異步模式(Event-based Asynchronous Pattern,EAP)。基于事件的異步編程的典型案例之一便是WebClient類:

var client = new WebClient();  client.DownloadStringCompleted += (sender, args) => {      var html = args.Result;      // ...  };   client.DownloadStringAsync(new Uri("http://www.51cto.com/"));

基于事件的異步模式的關鍵便在于,它是使用事件來作為工作結束時的通知機制。它和Begin/End的異步模型有明顯區別。例如,在發生錯誤時,對于Begin/End模型來說會在End方法調用時拋出異常,而對于基于事件的異步模式來說,它則是使用事件參數的Exception屬性來告訴程序員是否有異常發生。如果Exception屬性為null,則說明一切正常,否則它便返回異步調用過程中發生的異常。

在ASP.NET MVC中使用異步Action

當年我的Hack使用的是Begin/End異步編程模型,而ASP.NET MVC 2則使用了基于事件的異步模式。圍繞這種模式,ASP.NET MVC的AsyncController還提供了相關的輔助方法,讓異步Action的編寫變得相對容易一些。這里我則直接引用MSDN上的示例來說明問題。首先,我們準備一個普通的同步Action:

public class PortalController : Controller  {      public ActionResult News(string city)      {          var newnewsService = new NewsService();          var headlines = newsService.GetHeadlines(city);          return View(headlines);      }  }

與它等價的異步Action則為:

public class PortalController : AsyncController  {      public void NewsAsync(string city)      {          AsyncManager.OutstandingOperations.Increment();           var newnewsService = new NewsService();          newsService.GetHeadlinesCompleted += (sender, e) =>         {              AsyncManager.Parameters["headlines"] = e.Value;              AsyncManager.OutstandingOperations.Decrement();          };           newsService.GetHeadlinesAsync(city);      }       public ActionResult NewsCompleted(string[] headlines)      {          return View("News", headlines);      }  }

很顯然,異步Action也是標準的二段式調用,不過這個二段式調用卻由比較特別的“約定”。在ASP.NET MVC 2中使用異步Action時,首先需要繼承AsyncController類,并構造XyzAsync及XyzCompleted兩個方法,前者返回void,后者返回ActionResult——這便表示一個異步的Action,名為Xyz。

ASP.NET MVC 2中對于異步Action的開發也提供了一定支持,這個支持便來自于AsyncManager。在發起異步操作之前,我們可以調用其OutstandingOperations對象的Increment方法,表示需要“進行幾次異步操作”。

而每次異步操作結束之后,也就是在事件的處理函數中,便會調用對應的Decrement方法。這個方法表示“完成了一次異步操作”,而Decrement至零之后ASP.NET MVC便會得知所有的異步操作已經完成,于是便會調用XynCompleted方法,得到所需的ActionResult對象。

至于XyzCompleted方法所需要的參數,從代碼中便可看出是通過AsyncManager的Parameters集合進行“過渡”的。這里有個不是很理想的地方,便是使用了字符串這種“弱類型”的方式,假設參數名改變,則對應的字符串也需要跟著改變。

選擇Begin/End還是基于事件的異步模式?

很顯然,在ASP.NET MVC中使用既可以使用Begin/End或是基于事件的異步編程模式,因為ASP.NET MVC本身只是根據AsyncManager的行為來進行異步操作。不過在ASP.NET MVC中,似乎更看重的是基于事件的異步模式。我估計,這是由于兩種異步模式對于異常的行為差異所造成的吧。

正如我之前所提到的那樣,在使用Begin/End異步模式時,如果出現了錯誤則會在End方法調用時拋出異常。要知道在回調函數中拋出異常是異步編程中最危險的情況(有沒有之一?),如果沒有正確地進行捕獲則會讓整個進程崩潰——當然,我們也可以在配置文件中設置成“忽略”,但是這明顯也不妥當,例如會造成請求永遠無法結束,直至超時,并且有可能造成資源泄露。

與之相對,使用基于事件的異步模式則不會出現這個問題,因為在這種情況下,事件一定會被正確調用,而異常則永遠安安穩穩地保存在事件參數的Exception屬性中。因此,使用Begin/End則需要額外的try...catch進行保護,使用基于事件的異步編程模式則會讓代碼變得精簡一些。

當然,用著簡單,也只是因為那些異常已經被異步操作的“提供方”給處理了。試想,WebClient之所以可以通過事件參數來暴露異常,一定是因為在它內部使用了try...catch。同理,如果我們要實現一個基于事件的異步模式,例如上面的NewsService,那也一定少不了對異常進行仔細處理。

到此,相信大家對“ASP.NET基于事件的異步模式與異步Action怎么實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

龙胜| 东阿县| 阳江市| 葫芦岛市| 衡阳县| 扶沟县| 田阳县| 吉林市| 涞水县| 封开县| 精河县| 老河口市| 繁昌县| 扶绥县| 高雄市| 巴林左旗| 万宁市| 垫江县| 汶川县| 华阴市| 中西区| 江城| 大厂| 凯里市| 灵川县| 临武县| 大冶市| 阳曲县| 肃南| 云浮市| 攀枝花市| 松溪县| 阜新| 鹿邑县| 碌曲县| 家居| 莱芜市| 北辰区| 桂平市| 绥中县| 增城市|