2011-10-05 12 views
0

我聽說它在asp.net中使用ThreadPool很糟糕,但是我用它來教育自己。我的目標是確定Application_Error事件是否被觸發(在Global.asax中處理) - 我的答案是:不,它不會被觸發。代碼由於異常而在線程池中執行了無限次

但我觀察到一些奇怪的東西。我寫的線程只是將任務排隊到線程池。該任務旨在隨機拋出錯誤。但我觀察到,但我經常得到錯誤 - 數量超過了不。我排隊完成任務的時間。我有一個單獨的問題,即使是System.Diagnostics.Trace.WriteLine()不記錄消息到我的輸出窗口(視覺工作室)。爲什麼這個奇怪的行爲

using System; 
using System.Threading; 
namespace ThreadPoolDemo.Web 
{ 
    public partial class _default : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 

     } 

     protected void Button1_Click(object sender, EventArgs e) 
     { 
      Thread t = new Thread(createthreads); 
      t.IsBackground = true; 
      t.Start(); 
     } 

     void createthreads() 
     { 
      Thread.Sleep(10 * 1000); 
      int i; 
      System.Diagnostics.Trace.WriteLine("Queueing items"); 
      for (i = 0; i < 1; i++) 
       ThreadPool.QueueUserWorkItem(new WaitCallback(ErrorTask), null); 
      System.Diagnostics.Trace.WriteLine("End Queueing items"); 
     } 

     void ErrorTask(object obj) 
     { 
      Random generator = new Random(); 
      int value = generator.Next(1);    
      if (value == 0) 
       throw new Exception("Sample exception thrown"); 
      else 
       System.Diagnostics.Trace.WriteLine("Processed thread"); 
     } 

    } 
} 

回答

0

ErrorTask有兩個問題。首先是每次調用該方法時初始化一個新的Random實例。默認的Random構造函數使隨機數生成器的值爲Environment.TickCount,這對連續線程來說可能是相同的。所以你會得到多個線程相同的隨機序列。

更大的問題,不過,是generator.Next(1)將總是返回0 Random.Next(int max)產生一個隨機數,N,使得0 <= N < max。所以你的ErrorTask會拋出每個線程的異常。

我不知道如何或爲什麼它會拋出異常不止一次致ErrorTask。這似乎不可能。

我會建議作以下修改:

private Random generator = new Random(); 

void ErrorTask(object obj) 
{ 
    int value; 
    lock (generator) 
    { 
     value = generator.Next(2); 
    } 
    if (value == 0) 
     throw new Exception("Sample exception thrown"); 
    else 
     System.Diagnostics.Trace.WriteLine("Processed thread"); 
} 

generator現擁有一流的範圍,並且只初始化一次。 lock用於防止多個線程同時嘗試生成一個數字。如果沒有鎖定,隨機數字發生器可能會損壞,並且每次調用時都會返回0。我將參數更改爲generator.Next爲2,因此您可以獲得數字0和1.

+0

感謝您的信息。這很有幫助。你在VS IDE中嘗試過嗎?它發生在IDE內。但是,在iis v5.1上,我發現每次發生異常時,'aspnet_wp.exe'進程都會死亡,並以另一個進程ID再次出現。在事件日誌中,有4個條目對應於單個異常,即我猜想的第一個異常。我想這是不好的,如果它發生在維護會話數據在Web服務器的網站... – deostroll

+0

@deostroll:我沒有嘗試運行您的代碼。我的觀察結果基於檢查代碼。也許有一個很好的理由是人們不希望在asp.net應用程序中使用線程池。 –

相關問題