2011-03-29 68 views
5

我有一個ASP.NET MVC 3(.NET 4)Web應用程序。什麼是當前和推薦的方法來消除異步線程?

我有一個[HttpPost]行動方法,它將一些數據提交給數據庫。

現在,在這個方法完成後堅持存儲庫,我希望執行一個「背景」任務(想審計,或發送電子郵件等),我不關心結果(除非一個錯誤發生,在這種情況下,我會執行日誌記錄)。

我怎麼能/應該從我的操作方法中解除這個任務?

[HttpPost] 
[Authorize] 
public ActionResult Create(MyViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     _repo.Save(model); 
     // TODO: Fire off thread 
     return RedirectToRoute("Somepage", new { id = model.id }); 
    } 
    return View(model); 
} 

回答

4

新的.NET 4的方式做,這是一個Task

http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx

Task.Factory.StartNew(MyBackgroundAction); 

但對於這個簡單的操作,你只需要運行它,並不在乎協調任務,它只是作爲易於使用的線程池。

ThreadPool.QueueUserWorkItem(MyBackgroundAction) 

你想避免創建一個新的線程爲自己的每一個動作 - 稍後即會佔用更多的資源,是不必要的浪費。

如果您後臺任務的運行時間較長,您可能需要設置生產者/消費者隊列,並擁有一個或一組不斷運行的後臺線程來運行這些任務。

+0

感謝您的回答。一個澄清 - 「你想避免爲每一個行動自己創建一個新的線程 - 它會佔用更多的資源,是不必要的浪費」 - 我怎麼能做到這一點?然後我在哪裏創建新線程?例如,我在哪裏放置'ThreadPool.QueueUserWorkItem(MyBackgroundAction)'調用? – RPM1984 2011-03-29 02:37:40

+1

@ RPM1984使用QueueUserWorkItem意味着任務將由已經屬於ASP.Net線程池的線程完成。這些線程不斷地從隊列中消耗任務並完成它們,並且您可以在代碼中的任何地方排入新任務。不過,在我的回答中,這與ASP.Net中的主要缺點相關。 – 2011-03-29 02:43:03

+0

@Chris - 感謝您的幫助和解答。事情是,這是一個(相對)簡單的應用程序,沒有大量的流量或併發用戶。在過去的(版本1)中,我們使用了'Thread.Start',它很好。所以我想我會用'ThreadPool.QueueUserWorkItem'去。 – RPM1984 2011-03-29 03:34:48

0
// Fire off thread 
var t = new System.Threading.Thread(() => 
{ 
    // do whatever 
}); 
t.Start(); 

在 「作事」 你應該有try/catch語句,它記錄任何異常。

2

用於異步任務的通常是ill-advised to use the Thread Pool in ASP.Net

請注意,這個問題是關於here,雖然我不同意答案。被接受的答案假設你需要完成現在的工作,當這個問題描述的異步任務可以在以後輕鬆完成。這使得處理可以在更長的時間內傳播,當負載不均勻時(比如大多數網頁),這是有用的。

每個請求的產卵線程也不是最理想的,因爲沒有簡單的方法來限制創建的線程數。 100個衍生任務將與您的Web應用程序競爭,試圖做「實時」工作。

使用消息傳遞系統來管理不需要立即運行的異步任務。每個處理請求都會作爲一條消息發送,該消息將排隊等待稍後處理。然後,您可以在本地系統上安裝單獨的應用程序,或者如果這些任務需要在其他機器上進行相當多的處理。您也可以輕鬆地傳播這些任務的負載,方法是在同一隊列中的多臺機器上運行處理器。

以前我用MSMQ效果很好。

相關問題