一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - 詳解ASP.NET MVC下的異步Action的定義和執(zhí)行原理

詳解ASP.NET MVC下的異步Action的定義和執(zhí)行原理

2020-04-13 12:59蔣金楠 ASP.NET教程

這篇文章主要介紹了詳解ASP.NET MVC下的異步Action的定義和執(zhí)行原理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

Visual Studio提供的Controller創(chuàng)建向?qū)J(rèn)為我們創(chuàng)建一個(gè)繼承自抽象類Controller的Controller類型,這樣的Controller只能定義同步Action方法。如果我們需要定義異步Action方法,必須繼承抽象類AsyncController。這篇問你講述兩種不同的異步Action的定義方法和底層執(zhí)行原理。

一、基于線程池的請(qǐng)求處理

ASP.NET通過線程池的機(jī)制處理并發(fā)的HTTP請(qǐng)求。一個(gè)Web應(yīng)用內(nèi)部維護(hù)著一個(gè)線程池,當(dāng)探測(cè)到抵達(dá)的針對(duì)本應(yīng)用的請(qǐng)求時(shí),會(huì)從池中獲取一個(gè)空閑的線程來處理該請(qǐng)求。當(dāng)處理完畢,線程不會(huì)被回收,而是重新釋放到池中。線程池具有一個(gè)線程的最大容量,如果創(chuàng)建的線程達(dá)到這個(gè)上限并且所有的線程均被處于“忙碌”狀態(tài),新的HTTP請(qǐng)求會(huì)被放入一個(gè)請(qǐng)求隊(duì)列以等待某個(gè)完成了請(qǐng)求處理任務(wù)的線程重新釋放到池中。

我們將這些用于處理HTTP請(qǐng)求的線程稱為工作線程(Worker Thread),而這個(gè)縣城池自然就叫做工作線程池。ASP.NET這種基于線程池的請(qǐng)求處理機(jī)制主要具有如下兩個(gè)優(yōu)勢(shì):

  • 工作線程的重用:創(chuàng)建線程的成本雖然不如進(jìn)程的激活,卻也不是一件“一蹴而就”的事情,頻繁地創(chuàng)建和釋放線程會(huì)對(duì)性能造成極大的損害。而線程池機(jī)制避免了總是創(chuàng)建新的工作線程來處理每一個(gè)請(qǐng)求,被創(chuàng)建的工作線程得到了極大地重用,并最終提高了服務(wù)器的吞吐能力。
  • 工作線程數(shù)量的限制:資源的有限性具有了服務(wù)器處理請(qǐng)求的能力具有一個(gè)上限,或者說某臺(tái)服務(wù)器能夠處理的請(qǐng)求并發(fā)量具有一個(gè)臨界點(diǎn),一旦超過這個(gè)臨界點(diǎn),整臺(tái)服務(wù)將會(huì)因不能提供足夠的資源而崩潰。由于采用了對(duì)工作線程數(shù)量具有良好控制的線程池機(jī)制,ASP.NET MVC并發(fā)處理的請(qǐng)求數(shù)量不可能超過線程池的最大允許的容量,從而避免了在高并發(fā)情況下工作線程的無限制創(chuàng)建而最導(dǎo)致整個(gè)服務(wù)器的崩潰。

如果請(qǐng)求處理操作耗時(shí)較短,那么工作線程處理完畢后可以及時(shí)地被釋放到線程池中以用于對(duì)下一個(gè)請(qǐng)求的處理。但是對(duì)于比較耗時(shí)的操作來說,意味著工作線程將被長時(shí)間被某個(gè)請(qǐng)求獨(dú)占,如果這樣的操作訪問比較頻繁,在高并發(fā)的情況下意味著線程池中將可能找不到空閑的工作線程用于及時(shí)處理最新抵達(dá)請(qǐng)求。

如果我們采用異步的方式來處理這樣的耗時(shí)請(qǐng)求,工作線程可以讓后臺(tái)線程來接手,自己可以及時(shí)地被釋放到線程池中用于進(jìn)行后續(xù)請(qǐng)求的處理,從而提高了整個(gè)服務(wù)器的吞吐能力。值得一提的是,異步操作主要用于I/O綁定操作(比如數(shù)據(jù)庫訪問和遠(yuǎn)程服務(wù)調(diào)用等),而非CPU綁定操作,因?yàn)楫惒讲僮鲗?duì)整體性能的提升來源于:當(dāng)I/O設(shè)備在處理某個(gè)任務(wù)的時(shí)候,CPU可以釋放出來處理另一個(gè)任務(wù)。如果耗時(shí)操作主要依賴于本機(jī)CPU的運(yùn)算,采用異步方法反而會(huì)因?yàn)榫€程調(diào)度和線程上下文的切換而影響整體的性能。

二、兩種異步Action方法的定義

在了解了在AsyncController中定義異步Action方法的必要性之后,我們來簡單介紹一下異步Action方法的定義方式。總的來說,異步Action方法具有兩種定義方式,一種是將其定義成兩個(gè)匹配的方法XxxAsync/XxxCompleted,另一種則是定義一個(gè)返回類型為Task的方法。

XxxAsync/XxxCompleted

如果我們使用兩個(gè)匹配的方法XxxAsync/XxxCompleted來定義異步Action,我們可以將異步操作實(shí)現(xiàn)在XxxAsync方法中,而將最終內(nèi)容的呈現(xiàn)實(shí)現(xiàn)在XxxCompleted方法中。XxxCompleted可以看成是針對(duì)XxxAsync的回調(diào),當(dāng)定義在XxxAsync方法中的操作以異步方式執(zhí)行完成后,XxxCompleted方法會(huì)被自動(dòng)調(diào)用。XxxCompleted的定義方式和普通的同步Action方法比較類似。

作為演示,我在如下一個(gè)HomeController中定義了一個(gè)名為Article的異步操作來呈現(xiàn)指定名稱的文章內(nèi)容。我們將指定文章內(nèi)容的異步讀取定義在ArticleAsync方法中,而在ArticleCompleted方法中講讀取的內(nèi)容以ContentResult的形式呈現(xiàn)出來。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class HomeController : AsyncController
   {
     public void ArticleAsync(string name)
     {
       AsyncManager.OutstandingOperations.Increment();
       Task.Factory.StartNew(() =>
         {
           string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"\articles\{0}.html", name));
           using (StreamReader reader = new StreamReader(path))
          {
            AsyncManager.Parameters["content"] = reader.ReadToEnd();
          }
          AsyncManager.OutstandingOperations.Decrement();
        });
    }
    public ActionResult ArticleCompleted(string content)
    {
      return Content(content);
    }
  }

對(duì)于以XxxAsync/XxxCompleted形式定義的異步Action方法來說,ASP.NET MVC并不會(huì)以異步的方式來調(diào)用XxxAsync方法,所以我們需要在該方法中自定義實(shí)現(xiàn)異步操作的執(zhí)行。在上面定義的ArticleAsync方法中,我們是通過基于Task的并行編程方式來實(shí)現(xiàn)對(duì)文章內(nèi)容的異步讀取的。當(dāng)我們以XxxAsync/XxxCompleted形式定義的異步Action方法的時(shí)候,會(huì)頻繁地使用到Controller的AsyncManager屬性,該屬性返回一個(gè)類型為AsyncManager對(duì)象,我們將在下面一節(jié)對(duì)其進(jìn)行單獨(dú)講述。

在上面提供的實(shí)例中,我們?cè)诋惒讲僮鏖_始和結(jié)束的時(shí)候調(diào)用了AsyncManager的OutstandingOperations屬性的Increment和Decrement方法對(duì)于ASP.NET MVC發(fā)起通知。此外,我們還利用AsyncManager的Parameters屬性表示的字典來保存?zhèn)鬟f給ArticleCompleted方法的參數(shù),參數(shù)在字典中的Key(content)與ArticleCompleted的參數(shù)名稱是匹配的,所以在調(diào)用方法ArticleCompleted的時(shí)候,通過AsyncManager的Parameters屬性指定的參數(shù)值將自動(dòng)作為對(duì)應(yīng)的參數(shù)值。

Task返回值

如果采用上面的異步Action定義方式,意味著我們不得不為一個(gè)Action定義兩個(gè)方法,實(shí)際上我們可以通過一個(gè)方法來完成對(duì)異步Action的定義,那就是讓Action方法返回一個(gè)代表異步操作的Task對(duì)象。上面通過XxxAsync/XxxCompleted形式定義的異步Action可以采用如下的定義方式。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class HomeController AsyncController
  {
    public Task<ActionResult> Article(string name)
    {
      return Task.Factory.StartNew(() =>
        {
          string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"\articles\{0}.html", name));
          using (StreamReader reader = new StreamReader(path))
          {
           AsyncManager.Parameters["content"] = reader.ReadToEnd();
         }
       }).ContinueWith<ActionResult>(task =>
         {
           string content = (string)AsyncManager.Parameters["content"];
           return Content(content);
         });
   }
 }

上面定義的異步Action方法Article的返回類型為Task<ActionResult>,我們將異步文件內(nèi)容的讀取體現(xiàn)在返回的Task對(duì)象中。對(duì)文件內(nèi)容呈現(xiàn)的回調(diào)操作則通過調(diào)用該Task對(duì)象的ContinueWith<ActionResult>方法進(jìn)行注冊(cè),該操作會(huì)在異步操作完成之后被自動(dòng)調(diào)用。

如上面的代碼片斷所示,我們依然利用AsyncManager的Parameters屬性實(shí)現(xiàn)參數(shù)在異步操作和回調(diào)操作之間的傳遞。其實(shí)我們也可以使用Task對(duì)象的Result屬性來實(shí)現(xiàn)相同的功能,Article方法的定義也改寫成如下的形式。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class HomeController AsyncController
  {
    public Task<ActionResult> Article(string name)
    {
      return Task.Factory.StartNew(() =>
        {
          string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"\articles\{0}.html", name));
          using (StreamReader reader = new StreamReader(path))
          {
           return reader.ReadToEnd();
         }
       }).ContinueWith<ActionResult>(task =>
         {         
           return Content((string)task.Result);
         });
   }
 }

三、AsyncManager

在上面演示的異步Action的定義中,我們通過AsyncManager實(shí)現(xiàn)了兩個(gè)基本的功能,即在異步操作和回調(diào)操作之間傳遞參數(shù)和向ASP.NET MVC發(fā)送異步操作開始和結(jié)束的通知。由于AsyncManager在異步Action場(chǎng)景中具有重要的作用,我們有必要對(duì)其進(jìn)行單獨(dú)介紹,下面是AsyncManager的定義。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class AsyncManager
  
    public AsyncManager();
    public AsyncManager(SynchronizationContext syncContext);
  
    public EventHandler Finished;
  
    public virtual void Finish();
    public virtual void Sync(Action action);
   
   public OperationCounter OutstandingOperations { get; }
   public IDictionary<string, object> Parameters { get; }
   public int Timeout { get; set; }
 }
  
 public sealed class OperationCounter
 {
   public event EventHandler Completed; 
   
   public int Increment();
   public int Increment(int value);
   public int Decrement();
   public int Decrement(int value);
   
   public int Count { get; }
 }

如上面的代碼片斷所示,AsyncManager具有兩個(gè)構(gòu)造函數(shù)重載,非默認(rèn)構(gòu)造函數(shù)接受一個(gè)表示同步上下文的SynchronizationContext對(duì)象作為參數(shù)。如果指定的同步上下文對(duì)象為Null,并且當(dāng)前的同步上下文(通過SynchronizationContext的靜態(tài)屬性Current表示)存在,則使用該上下文;否則創(chuàng)建一個(gè)新的同步上下文。該同步上下文用于Sync方法的執(zhí)行,也就是說在該方法指定的Action委托將會(huì)在該同步上下文中以同步的方式執(zhí)行。

AsyncManager的核心是通過屬性O(shè)utstandingOperations表示的正在進(jìn)行的異步操作計(jì)數(shù)器,該屬性是一個(gè)類型為OperationCounter的對(duì)象。操作計(jì)數(shù)通過只讀屬性Count表示,當(dāng)我們開始和完成異步操作的時(shí)候分別調(diào)用Increment和Decrement方法作增加和介紹計(jì)數(shù)操作。Increment和Decrement各自具有兩個(gè)重載,作為整數(shù)參數(shù)value(該參數(shù)值可以是負(fù)數(shù))表示增加或者減少的數(shù)值,如果調(diào)用無參方法,增加或者減少的數(shù)值為1。如果我們需要同時(shí)執(zhí)行多個(gè)異步操作,則可以通過如下的方法來操作計(jì)數(shù)器。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
AsyncManager.OutstandingOperations.Increment(3);
  
  Task.Factory.StartNew(() =>
  {
    //異步操作1
    AsyncManager.OutstandingOperations.Decrement();
  });
  Task.Factory.StartNew(() =>
  {
   //異步操作2
   AsyncManager.OutstandingOperations.Decrement();
 });
 Task.Factory.StartNew(() =>
 {
   //異步操作3
   AsyncManager.OutstandingOperations.Decrement();
 });

對(duì)于每次通過Increment和Decrement方法調(diào)用引起的計(jì)數(shù)數(shù)值的改變,OperationCounter對(duì)象都會(huì)檢驗(yàn)當(dāng)前計(jì)數(shù)數(shù)值是否為零,如果則表明所有的操作運(yùn)行完畢,如果預(yù)先注冊(cè)了Completed事件,該事件會(huì)被觸發(fā)。值得一提的時(shí)候,表明所有操作完成執(zhí)行的標(biāo)志是計(jì)數(shù)器的值等于零,而不是小于零,如果我們通過調(diào)用Increment和Decrement方法使計(jì)數(shù)器的值稱為一個(gè)負(fù)數(shù),注冊(cè)的Completed事件是不會(huì)被觸發(fā)的。

AsyncManager在初始化的時(shí)候就注冊(cè)了通過屬性O(shè)utstandingOperations表示的OperationCounter對(duì)象的Completed事件,使該事件觸發(fā)的時(shí)候調(diào)用自身的Finish方法。而虛方法Finish在AsyncManager中的默認(rèn)實(shí)現(xiàn)又會(huì)觸發(fā)自身的Finished事件。

如下面的代碼片斷所示,Controller類實(shí)現(xiàn)了IAsyncManagerContainer接口,而后者定義了一個(gè)只讀屬性AsyncManager用于提供輔助執(zhí)行異步Action的AsyncManager對(duì)象,而我們?cè)诙x異步Action方法是使用的AsyncManager對(duì)象就是從抽象類Controller中集成下來的AsyncManager屬性。

?
1
2
3
4
5
6
7
8
9
public abstract class Controller ControllerBase, IAsyncManagerContainer,...
 {
   public AsyncManager AsyncManager { get; }
 }
 
 public interface IAsyncManagerContainer
 
   AsyncManager AsyncManager { get; }
 }

四、Completed方法的執(zhí)行

對(duì)于通過XxxAsync/XxxCompleted形式定義的異步Action,我們說回調(diào)操作XxxCompleted會(huì)在定義在XxxAsync方法中的異步操作執(zhí)行結(jié)束之后被自動(dòng)調(diào)用,那么XxxCompleted方法具體是如何被執(zhí)行的呢?

異步Action的執(zhí)行最終是通過描述該Action的AsyncActionDescriptor對(duì)象的BeginExecute/EndExecute方法來完成的。通過之前“Model的綁定”的介紹我們知道通過XxxAsync/XxxCompleted形式定義的異步Action通過一個(gè)ReflectedAsyncActionDescriptor對(duì)象來表示的,ReflectedAsyncActionDescriptor在執(zhí)行BeginExecute方法的時(shí)候會(huì)注冊(cè)Controller對(duì)象的AsyncManager的Finished事件,使該事件觸發(fā)的時(shí)候去執(zhí)行Completed方法。

也就是說針對(duì)當(dāng)前Controller的AsyncManager的Finished事件的觸發(fā)標(biāo)志著異步操作的結(jié)束,而此時(shí)匹配的Completed方法會(huì)被執(zhí)行。由于AsyncManager的Finish方法會(huì)主動(dòng)觸發(fā)該事件,所以我們可以通過調(diào)用該方法使Completed方法立即執(zhí)行。由于AsyncManager的OperationCounter對(duì)象的Completed事件觸發(fā)的時(shí)候會(huì)調(diào)用Finish方法,所以當(dāng)表示當(dāng)前正在執(zhí)行的異步操作計(jì)算器的值為零時(shí),Completed方法也會(huì)自動(dòng)被執(zhí)行。

如果我們?cè)赬xxAsync方法中通過如下的方式同時(shí)執(zhí)行三個(gè)異步操作,并在每個(gè)操作完成之后調(diào)用AsyncManager的Finish方法,意味著最先完成的異步操作會(huì)導(dǎo)致XxxCompleted方法的執(zhí)行。換句話說,當(dāng)XxxCompleted方法執(zhí)行的時(shí)候,可能還有兩個(gè)異步操作正在執(zhí)行。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
AsyncManager.OutstandingOperations.Increment(3);
 
 Task.Factory.StartNew(() =>
 {
   //異步操作1
   AsyncManager.Finish();
 });
 Task.Factory.StartNew(() =>
 {
  //異步操作2
  AsyncManager.Finish();
});
Task.Factory.StartNew(() =>
{
  //異步操作3
  AsyncManager.Finish();
});

如果完全通過為完成的異步操作計(jì)數(shù)機(jī)制來控制XxxCompleted方法的執(zhí)行,由于計(jì)數(shù)的檢測(cè)和Completed事件的觸發(fā)只發(fā)生在OperationCounter的Increment/Decrement方法被執(zhí)行的時(shí)候,如果我們?cè)陂_始和結(jié)束異步操作的時(shí)候都沒有調(diào)用這兩個(gè)方法,XxxCompleted是否會(huì)執(zhí)行呢?同樣以之前定義的用語讀取/顯示文章內(nèi)容的異步Action為例,我們按照如下的方式將定義在ArticleAsync方法中針對(duì)AsyncManager的OutstandingOperations屬性的Increment和Decrement方法調(diào)用注釋調(diào)用,ArticleCompleted方法是否還能正常運(yùn)行呢?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class HomeController AsyncController
 {
   public void ArticleAsync(string name)
   {
     //AsyncManager.OutstandingOperations.Increment();
     Task.Factory.StartNew(() =>
       {
         string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"\articles\{0}.html", name));
         using (StreamReader reader = new StreamReader(path))
        {
          AsyncManager.Parameters["content"] = reader.ReadToEnd();
        }
        //AsyncManager.OutstandingOperations.Decrement();
      });
  }
  public ActionResult ArticleCompleted(string content)
  {
    return Content(content);
  }
}

實(shí)際上ArticleCompleted依然會(huì)被執(zhí)行,但是這樣我們就不能確保正常讀取文章內(nèi)容,因?yàn)锳rticleCompleted方法會(huì)在ArticleAsync方法執(zhí)行之后被立即執(zhí)行。如果文章內(nèi)容讀取是一個(gè)相對(duì)耗時(shí)的操作,表示文章內(nèi)容的ArticleCompleted方法的content參數(shù)在執(zhí)行的時(shí)候尚未被初始化。在這種情況下的ArticleCompleted是如何被執(zhí)行的呢?

原因和簡單,ReflectedAsyncActionDescriptor的BeginExecute方法在執(zhí)行XxxAsync方法的前后會(huì)分別調(diào)用AsyncManager的OutstandingOperations屬性的Increment和Decrement方法。對(duì)于我們給出的例子來說,在執(zhí)行ArticleAsync之前Increment方法被調(diào)用使計(jì)算器的值變成1,隨后ArticleAsync被執(zhí)行,由于該方法以異步的方式讀取指定的文件內(nèi)容,所以會(huì)立即返回。最后Decrement方法被執(zhí)行使計(jì)數(shù)器的值變成0,AsyncManager的Completed事件被觸發(fā)并導(dǎo)致ArticleCompleted方法的執(zhí)行。而此時(shí),文件內(nèi)容的讀取正在進(jìn)行之中,表示文章內(nèi)容的content參數(shù)自然尚未被初始化。

ReflectedAsyncActionDescriptor這樣的執(zhí)行機(jī)制也對(duì)我們使用AsyncManager提出了要求,那就是對(duì)尚未完成的一步操作計(jì)數(shù)器的增加操作不應(yīng)該發(fā)生在異步線程中,如下所示的針對(duì)AsyncManager的OutstandingOperations屬性的Increment方法的定義是不對(duì)的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class HomeController AsyncController
 {
   public void XxxAsync(string name)
   {
     Task.Factory.StartNew(() =>
       {
         AsyncManager.OutstandingOperations.Increment();
          //...
          AsyncManager.OutstandingOperations.Decrement();
      });
  }
  //其他成員
}

下面采用正確的定義方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class HomeController AsyncController
  {
    public void XxxAsync(string name)
   {
     AsyncManager.OutstandingOperations.Increment();
      Task.Factory.StartNew(() =>
        {
          //...
          AsyncManager.OutstandingOperations.Decrement();
       });
   }
   //其他成員
 }

最后再強(qiáng)調(diào)一點(diǎn),不論是顯式調(diào)用AsyncManager的Finish方法,還是通過調(diào)用AsyncManager的OutstandingOperations屬性的Increment方法是計(jì)數(shù)器的值變成零,僅僅是讓XxxCompleted方法得以執(zhí)行,并不能真正阻止異步操作的執(zhí)行。

五、異步操作的超時(shí)控制

異步操作雖然適合那些相對(duì)耗時(shí)的I/O綁定型操作,但是也并不說對(duì)一步操作執(zhí)行的時(shí)間沒有限制。異步超時(shí)時(shí)限通過AsyncManager的整型屬性Timeout表示,它表示超時(shí)時(shí)限的總毫秒數(shù),其默認(rèn)值為45000(45秒)。如果將Timeout屬性設(shè)置為-1,意味著異步操作執(zhí)行不再具有任何時(shí)間的限制。對(duì)于以XxxAsync/XxxCompleted形式定義的異步Action來說,如果XxxAsync執(zhí)行之后,在規(guī)定的超時(shí)時(shí)限中XxxCompleted沒有得到執(zhí)行,一個(gè)TimeoutException會(huì)被拋出來。

如果我們以返回類型為Task的形式定義異步Action,通過Task體現(xiàn)的異步操作的執(zhí)行時(shí)間不受AsyncManager的Timeout屬性的限制。我們通過如下的代碼定義了一個(gè)名為Data的異步Action方法以異步的方式獲取作為Model的數(shù)據(jù)并通過默認(rèn)的View呈現(xiàn)出來,但是異步操作中具有一個(gè)無限循環(huán),當(dāng)我們?cè)L問該Data方法時(shí),異步操作將會(huì)無限制地執(zhí)行下去,也不會(huì)有TimeoutException異常發(fā)生。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class HomeController AsyncController
 {
   public Task<ActionResult> Data()
   {
     return Task.Factory.StartNew(() =>
     {
       while (true)
       { }
       return GetModel();
        
    }).ContinueWith<ActionResult>(task =>
    {
      object model = task.Result;
      return View(task.Result);
    });
  }
  //其他成員
}

在ASP.NET MVC應(yīng)用編程接口中具有兩個(gè)特殊的特性用于定制異步操作執(zhí)行的超時(shí)時(shí)限,它們是具有如下定義的AsyncTimeoutAttribute和NoAsyncTimeoutAttribute,均定義在命名空間System.Web.Mvc下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited=true, AllowMultiple=false)]
 public class AsyncTimeoutAttribute ActionFilterAttribute
 {
   
   public AsyncTimeoutAttribute(int duration);
   public override void OnActionExecuting(ActionExecutingContext filterContext); 
   public int Duration { get; }
 }
 
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited=true, AllowMultiple=false)]
public sealed class NoAsyncTimeoutAttribute AsyncTimeoutAttribute
{
  // Methods
  public NoAsyncTimeoutAttribute() base(-1)
  {
  }
}

從上面給出的定義我們可以看出這兩個(gè)特性均是ActionFilter。AsyncTimeoutAttribute的構(gòu)造函數(shù)接受一個(gè)表示超時(shí)時(shí)限(以毫秒為單位)的整數(shù)作為其參數(shù),它通過重寫OnActionExecuting方法將指定的超時(shí)時(shí)限設(shè)置給當(dāng)前Controller的AsyncManager的Timeout屬性進(jìn)行。NoAsyncTimeoutAttribute是AsyncTimeoutAttribute的繼承者,它將超時(shí)時(shí)限設(shè)置為-1,意味著它解除了對(duì)超時(shí)的限制。

從應(yīng)用在這兩個(gè)特性的AttributeUsageAttribute定義可看出,它們既可以應(yīng)用于類也可以用于也方法,意味著我們可以將它們應(yīng)用到Controller類型或者異步Action方法(僅對(duì)XxxAsync方法有效,不能應(yīng)用到XxxCompleted方法上)。如果我們將它們同時(shí)應(yīng)用到Controller類和Action方法上,針對(duì)方法級(jí)別的特性無疑具有更高的優(yōu)先級(jí)。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://www.cnblogs.com/artech/archive/2012/06/20/async-action-in-mvc.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 99久久精彩视频 | 全日爱韩国视频在线观看 | 香蕉动漫库 | 色网在线视频 | 成人福利网站 | 啪一啪在线视频 | 精品suv一区二区三区 | 成 人 亚洲 综合天堂 | 日本一在线中文字幕天堂 | 精品国产乱码久久久久久软件 | 香蕉91视频 | 大伊人青草狠狠久久 | 国产好深好硬好爽我还要视频 | 日本一区二区三区在线 观看网站 | 60岁妇女毛片免费观看 | 免费视频完整版在线观看网站 | 午夜免费体验30分 | 波多野结中文字幕在线69视频 | 插鸡视频在线观看 | 91国内精品久久久久影院优播 | 国产亚洲精品自在线亚洲情侣 | 久久久久久免费观看 | 国产一区二区在线观看美女 | 亚洲成人三级 | 国产一区二区三区高清 | 免费在线视频网站 | 亚洲一卡2卡三卡4卡5卡组 | 日本68xxxxxxxxx24| 手机在线免费观看日本推理片 | 亚洲精品123区在线观看 | 日本黄色录像视频 | 金莲你下面好紧夹得我好爽 | 精品国产一区二区 | 麻豆在线传煤 | 雪恋电影完整版免费观看 | 欧美日韩一区二区中文字幕视频 | 国产欧美成人免费观看 | 日本在线观看a | 91高清免费国产自产 | 日韩亚洲欧美综合一区二区三区 | 高清视频在线观看+免费 |