2011-04-05 70 views
8

我正在使用.NET 4構建一個網站。有許多MSDN文章約會從2003, about using Thread objects2007, using Asynchronous Pages in .NET 2,但這是非常陳舊。我知道.NET 4給我們帶來了Task classsome people vaguely cautioning against its use for this purpose我應該如何在ASP.NET 4中執行長時間運行的任務?

所以我問你,什麼是大約2011年的「首選」方法在IIS 4下運行背景/異步工作?關於直接使用線程/任務有哪些警告? Async = true仍然流行嗎?

編輯:好的,好的,從答案很明顯,意見是我應該提供服務,如果我可以。但是在webapp中做這件事的好處是很重要的,特別是更容易的部署/重新部署。假設這個過程是安全的,那麼,如果我在IIS內部完成這個過程,最好的方法是什麼?

回答

15

優先避免在這樣的環境中執行長時間的任務。

通過互操作性將長時間運行的任務委託給穩定的系統服務,從而使Web應用程序響應並且只需要直接用戶請求。

Web應用程序從未(也不是)被認爲是可靠的系統 - 任何曾經使用過瀏覽器的人都會遇到(至少)超時,可以肯定的是;這樣的不便(對於雙方來說)並不限於這種情況。當然,任何系統都可能會崩潰,但圍繞系統內置的持久性的情況應該完全例外。

Windows服務旨在長時間運行,如果出現問題,您通常比您的個人服務更擔心。

+0

在WAWS上,使用Azure WebJobs – RickAndMSFT 2014-01-21 01:26:52

0

我的首選方法與Robert Harvey在他的回答中提出的方法相同。

您仍然可以使用Task Parallel Library,但在IIS之外的獨立進程中啓動任務(原因是IIS具有有限數量的工作線程分發並施加其他限制,從而可能導致長時間運行的任務不可預測)。

+0

您是否有這方面的一個快速示例? – Tigran 2013-02-06 09:29:08

0

您可以創建一個像線程號爲http://www.dotnetperls.com/threadpool這樣的靜態線程池(例如只有2個)。然後將任務排入其中,但極不推薦,因爲Web服務器不適合執行此類任務

0

這是對「每日一次」方案的描述。

如果你真的想避免創建一個服務,你可以用1分鐘的間隔啓動一個計時器。每個定時器委託被調用時,你就要跑是這樣的(僞代碼):

lastInvokeDay = LoadLastInvokeDate(); 
If (lastInvokeDay < DateTime.Now.Date && timeOfDayToRun == DateTime.Now.Time) 
{ 
    try 
    { 
    today = DateTime.Now.Date; 
    runMyTask(); 
    } 
    catch.. 
    finally 
    { 
    lastInvokeDay = today; 
    SaveLastInvokeDay(lastInvokeDay); 
    } 
} 

請記住,lastInvokeDay要麼在數據庫或文件被保留...

現在,如果要啓用立即調用任務,則可以根據需要簡單地調用runMyTask()。 如果對於保持runMyTask每天不止一次發生重要,可以在其中創建一個同步代碼塊(使用lock語句),並將lastInvokeDay檢查移入其中。

這是回答您的問題嗎?