2012-11-01 52 views
1

我在ASP.NET項目,昨天的工作,我看到了一段代碼,使用System.Threading.Thread卸載一些任務,以一個新的線程。該線程運行幾條SQL語句並記錄結果。ASP.NET和多線程最佳實踐

使用另一種方法不是更好嗎?例如,要有一個執行SQL批處理的Windows服務。然後,網頁將通過WCF排隊(僅通過WCF)。

在一般情況下,是什麼在ASP.NET多線程的最佳實踐?是否有線程/ TPL任務的合理用法/等等。在一個網頁?

+0

請解釋爲什麼您認爲在另一個進程中執行SQL查詢會更好。 – Dai

+0

我的主要擔心是每個Web請求都有一個線程。這有效地加倍了線程,我認爲這不是一個好主意,特別是當有許多併發用戶時。可能最好在表中寫入批處理參數,並使用SQL Server作業稍後執行實際查詢。 –

回答

2

我想,當ASP.NET中使用多線程:像你這樣的改變的web.config或在一段時間內,以避免內存泄漏

  1. ASP.NET回收因某些原因的AppDomain。問題是你不知道回收的確切時間。長時間運行的線程不適合,因爲當ASP.NET回收時它會相應地減少線程。正確這種情況的辦法是長時間運行的任務應該通過Queue在後臺進程上運行,就像你提到的一樣。

  2. 對於短期運行和消防忘記任務TPL異步/等待是最合適的,因爲它沒有阻止線程池線程利用HTTP請求。

0

在我看來,這應該通過提高某些種類標誌的數據庫和一個Windows服務,定期檢查標誌,並開始工作來解決。如果作業過於頻繁,應使用專用隊列解決方案(MSMQ,RabbitMQ等)以避免數據庫過載或表增長過快。我不認爲通過WCF直接與Windows服務進行通信或其他任何事情都是一個好主意,因爲這可能會導致郵件丟失。

話雖這麼說,有時一個項目需要在一個共享的主機,不能設置一個專用的Windows服務運行。在這種情況下,一個線程是可以接受的,因爲只要項目增長到擁有自己的服務器,就應該儘快刪除線程。

我相信ASP.NET中的所有其他線程是一個問題的標誌,除了使用任務來表示異步操作,或者極少數情況下,當您想在Web項目中並行執行計算但您的項目有極少數併發用戶(併發用戶數超過核心數量更少)

爲什麼任務ASP.NET中有用嗎?

使用任務進行異步操作的第一個原因是從.NET 4.5開始,異步API返回任務:) 異步操作(不要與並行計算混淆)可能是Web服務調用,數據庫調用等。對兩件事情有用:

  1. 同時激發其中的幾個,你的工作需要的時間等於最長的操作。如果你以順序(非異步)方式觸發它們,它們需要的時間等於每個操作的時間總和,這顯然更多。
  2. 它們可以通過釋放執行頁面的線程來提高可伸縮性 - Node.js風格。 ASP.NET自始至終支持這一點,但在4.5版本中它確實很容易使用。我會盡可能聲稱由於異步/等待而比Node.js更容易。釋放線程很重要,因爲您可能會通過讓它們等待而耗盡您的線程。結果就是,當有一定數量的用戶時,儘管事實上CPU使用率只有30%,因爲新請求在隊列中等待,但您的網站變得很慢。如果增加線程池中的線程數量,則支付恆定上下文切換的代價而不是OS。在某些時候,您將獲得100%的CPU使用率,但其中40%將用於上下文切換。您將增加吞吐量但收益遞減。大量的線程也增加了內存佔用。
+0

我同意一般。起初我想過使用Windows服務,但現在我認爲使用SQL Server作業就足夠了。不需要MSMQ,RabbitMQ或其他。儘管如此,我仍然沒有看到TPL任務應該用於異步操作的原因。此外,我沒有看到一個合理的方案,在Web服務器上的異步操作適用。你能詳細說明嗎? –

+0

更新了我的答案。 – Stilgar

+0

我想可能會出現TPL任務適合的場景,儘管我現在想不出任何情況。一般來說,我認爲Web服務器上不應該有多線程。應該使用所有可用的資源(線程)來爲請求提供服務。如果你有很多併發用戶,你最終會得到很多線程。如果有Web請求或I/O完成端口,則無關緊要。在某個時候,服務器將變得過載。您始終可以構建應用程序邏輯,以便支持短序列化請求,而不是(長)並行任務。 –