2013-02-27 87 views
1

我有一個任務需要在控制器處理請求之後執行,並且響應正在返回客戶端。爲此,我重寫了我的控制器上的OnActionExecuted()事件,並調用此方法中的任務。在asp.net MVC控制器上執行異步OnAction

由於任務可能需要一些時間才能運行,並且返回void,所以我想要異步調用它,以便重寫的OnActionExecuted()方法可以立即返回,並且可以在任務執行時將響應發送到客戶端。我曾嘗試用下面的代碼來實現這一點,使用Task.Run()(在.NET 4.5)

protected override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    Task.Run(() => WrapUp()); 
} 

然而,這並不產品預期的效果。當我遍歷代碼時,它仍然同步執行 - 在OnActionExecuted()方法退出之前調用WrapUp()方法中的所有內容。當WrapUp()方法掛起時,客戶端會在收到響應之前等待任務完成。

我需要做什麼才能使這項工作按預期進行?

回答

3

OnActionExecuted將立即返回,因爲您只在創建和啓動任務。你正在觀察的行爲是不正常的。如果您嘗試以下操作,會發生什麼情況:

protected override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    Task.Run(() => Thread.Sleep(10000)); 
} 

客戶端不等待10秒鐘才能得到結果,是嗎?

+0

是的,你是正確的,客戶端不必等待Thread.Sleep()。我觀察到的行爲非常奇怪,因爲每次發出請求時都不一致 - 但在我逐步完成時總會有一定程度的等待時間。我可以看到OnActionExecuted方法退出,但即使在這一點之後,瀏覽器仍然在等待響應。 – Nick 2013-02-27 12:53:53

+0

詳細說明,WrapUp方法實際上調用了控制器上注入依賴項的方法,該方法依次調用更多注入依賴項(我使用StructureMap for IoC)的方法。當我逐步完成調用堆棧的後期階段時,最終似乎會得到響應。它似乎在等待,直到部分或全部注入的依賴已經從內存中釋放出來 - 這可能嗎? – Nick 2013-02-27 12:54:25

+0

那麼,瀏覽器在'OnActionExecuted'方法之後應該等待是正常的。這不是執行管道中的最後一種方法。事後還有很多事情要做。諸如尋找,準備和渲染視圖本身也需要一些時間。例如'OnResultExecuting','OnResultExecuted'等方法,... – 2013-02-27 12:56:13