2010-10-24 40 views

回答

8

首先,ASP.NET線程池和CLR線程池之間沒有區別。 ASP.NET在CLR線程池上處理頁面,因此您的ASP.NET頁面將始終具有IsThreadPoolThread == true。

我很好奇你是如何創建你的線程。您是使用System.Threading.Thread構造函數,還是使用ThreadPool.QueueUserWorkItem?如果您使用的是ThreadPool.QueueUserWorkItem,那麼您得到的線程來自常規.net線程池。

最後,因爲我有posted before,從ASP.NET內部嘗試長時間運行的任務總是一個壞主意。我的一般建議是使用後臺windows服務來處理這些請求,因爲ASP.NET可能隨時終止您的後臺線程。更多細節在這裏,如果你必須在IIS中執行它:http://csharpfeeds.com/post/5415/Dont_use_the_ThreadPool_in_ASP.NET.aspx

+0

當然,從asp.net手動構建一個新的線程不會導致IsThreadPoolThread被設置爲true,對嗎?所以他必須調用QueueUserWorkItem。如果我錯了,請糾正我。 – Fantius 2011-02-08 05:20:05

+0

對,我只是爲了自己的理智而斷言。 – 2011-02-08 14:27:24

+0

我從'System.Threading.Thread'創建新線程。 – Xaqron 2011-02-08 15:31:17

4

儘管要儘量減少對事務的影響並迎合分佈式事務中不可預見的問題,但在本例中,實際上並不需要重新創建IIS因爲這個過程很長時間。整個「IIS可以隨時死亡」的模因是恕我直言,大大誇張。

是的,您可以手動重新啓動IIS或應用程序池,但是您也可以重新啓動任何其他服務,爲同樣的效果執行相同的工作。至於自動回收,IIS使用重疊的工作進程,並且不會強制終止已啓動的線程(除非發生超時)。如果是這樣的話,我們會遇到任何託管應用程序的嚴重問題(什麼是阻止IIS在啓動後的0.001ms之內終止快速響應線程)

本質上,讓IIS做IIS最擅長的工作,不要堅持在同步操作中,你只會浪費池的線程等待阻塞I/O,這是我相信你試圖避免的。您已經通過轉向異步處理程序(ASHX)做出了一個不錯的選擇,使用IHttpAsyncHandler實現來生成自定義線程,然後在不影響Web應用程序及其池的情況下阻止您的心願。一旦你啓動了一個異步操作線程,asp.net線程將返回到它自己的池,並準備開始提供新的請求。在一個池中有100個線程的默認限制,並且考慮到你的進程在cpu上佔用很少的帶寬,我懷疑你在耗盡管道空間之前會耗盡池線程:)。關於如何建立異步處理程序檢查此鏈接的詳細信息(它的一篇舊文,但有效的非以內):

Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code

2

其實也有在ASP .NET線程的區別:工作線程和IO線程(我相信你聲明爲CLR線程的系統線程)。

現在,ASP .NET在每個請求上都使用一個工作線程,除非使用自定義配置,並且這些工作線程限制您的CPU號;這個配置可以在IIS中設置。 當您通過使用委託在ASP.NET中啓動異步任務時,您正在使用另一個工作線程。代表是一種快速而骯髒的方式來啓動異步操作。NET :)

如果你想啓動一個新的線程不會佔用工作線程,那麼你必須明確地啓動一個新的線程,如:new Thread()....等。現在這帶有很多代碼管理,並且不遵循基於事件的異步模式。 但是,有一種方法可以安全地啓動異步線程,也就是說,通過使用.NET在對象上使用自己的異步方法。事情你通常會使用異步SQL命令,Web服務調用等。所有這些都有一個BEGIN和一個END方法。 通過使用這些方法,您將永遠不會使用工作線程,而是使用IO線程。

當談到異步頁面時,ASP .NET有一些小竅門。 有兩種選擇:

  1. 異步頁面:它讓你的頁面循環變得異步。這基本上意味着該頁面被請求異步。
  2. 異步頁面任務:它允許您定義在頁面啓動時將觸發異步的任務。它有點像Asynch線程,只是ASP.NET爲你做了很多事情,而且它更受限制。

我沒有所有的細節,但請看看MSDN Library上的兩個選項。 這裏是關於這個問題的文章:asynch programmin