2012-11-26 82 views
2

在應用程序中有2頁,CompletePoll.aspx,Default.aspx。如何避免TypeInitializer異常?

CompletePoll.aspx - >的Page_Load()

  Ultoo u = new Ultoo(); 
      u.UserName = Request["username"].ToString(); 
      u.Password = Request["password"].ToString(); 
      new Thread(u.CompletePoll).Start(); 

CompletePoll()

  ....... 
      ....... 
      String str = "Question:" + QuestionGenerator.GetNextQuestion(); /*Here i am getting Type initializer exception*/ 
      ....... 
      ....... 

QuestionGenerator

  public static class QuestionGenerator 
      { 
       private static string[] FirstParts = new StreamReader(HttpContext.Current.Server.MapPath("App_Data/QuestionPart1.txt")).ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 
       private static string[] SecondParts = new StreamReader(HttpContext.Current.Server.MapPath("App_Data/QuestionPart2.txt")).ReadToEnd(). Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 
       private static Random r = new Random(); 

       public static string GetNextQuestion() 
       { 
        return FirstParts[r.Next(0, FirstParts.Length - 1)] + " " + SecondParts[r.Next(0, SecondParts.Length - 1)] + "?"; 
       } 
      } 

但是,如果我先調用Default.aspx,然後CompletePoll.aspx代碼工作正常。

的Default.aspx - >的Page_Load()

  Label1.Text = QuestionGenerator.GetNextQuestion(); 

所以在這裏我的問題是,如果我訪問CompletePoll.aspx 第一我收到TypeInitializer例外。如果我先訪問Default.aspx,然後CompletePoll.aspx,我沒有得到任何問題。我的代碼有什麼問題,我錯過了什麼?我如何首先訪問CompletePoll.aspx?

+0

什麼是內部異常? – akatakritos

+0

InnerException:System.NullReferenceException HResult = -2147467261 Message =未將對象引用設置爲對象的實例。來源= WebTracing StackTrace:在UltooAgent.QuestionGenerator..cctor()在c:\ Users \ Rajeev \ Desktop \ Tracing \ Tracing \ Tracing \ WebTracing \ WebTracing \ QuestionGe nerator.cs:line 12 – Rajeev

回答

1
private static string[] FirstParts = new StreamReader(HttpContext.Current.Server.MapPath("App_Data/QuestionPart1.txt")).ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 

這是不對的。這將檢查HttpContext.Current一次,當類型被初始化時,保存結果,並且不會再嘗試再次讀取它。第一次成功時再次檢查可能是正確的,但第一次需要HttpContext.Current不是null。如果第一次嘗試導致異常,則稍後將不會重新初始化。你不能確定什麼時候該類被初始化,所以你不能確定HttpContext.Current是否被設置在那個點上(並且如果你從一個線程調用它,它將不會被設置)。

此外,這不會調用StreamReader.Dispose,所以它會讓讀取器和文件本身保持打開狀態,直到垃圾收集器正常運行。

一個更安全的方法是像

private static string[] firstParts; // field 

private static string[] FirstParts // property 
{ 
    get 
    { 
     if (firstParts == null) 
     { 
      using (var reader = new StreamReader(HttpContext.Current.Server.MapPath("App_Data/QuestionPart1.txt"))) 
       firstParts = reader.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 
     } 
     return firstParts; 
    } 
} 

這將確保reader.Dispose()被調用,將確保該文件被讀取時,物業首次訪問時的類型被初始化而不是,將確保任何例外實際上都會以更直接的方式告訴您發生了什麼,並且確保其餘類型可用,即使FirstParts無法設置。

但是,它仍然要求您不要從線程讀取FirstParts。您可以通過閱讀它避免這樣的問題,一旦開始線程之前:

Ultoo u = new Ultoo(); 
u.UserName = Request["username"].ToString(); 
u.Password = Request["password"].ToString(); 
QuestionGenerator.Initialize(); // from the main thread 
new Thread(u.CompletePoll).Start(); 


public static class QuestionGenerator 
{ 
    public static void Initialize() 
    { 
     var firstParts = FirstParts; 
     var secondParts = SecondParts; 
     // merely reading the properties is enough to initialise them, so ignore the results 
    } 
} 

一旦線程開始,Initialize()被稱爲後,你可以訪問FirstPartsSecondParts可靠。

+0

謝謝你您的寶貴信息,我根據您的說法做出了修改,並對我有用。 順便說一下,我還發現另一個解決方案,它將允許我找到文件「QuestionParts1.txt」的路徑,而不使用HttpContext.Current對象。以下是我可以從線程中找到路徑的屬性。 HttpRuntime.AppDomainAppPath + @「App_Data \ QuestionPart1.txt」 – Rajeev

+0

@Rajeev這看起來也不錯。如果你採用這種方式,我個人推薦'Path.Combine(HttpRuntime.AppDomainAppPath,「App_Data」,「QuestionPart1.txt」)',但是你在做的簡單字符串連接應該在這種情況下給出相同的結果。 – hvd

0

您需要查看內部異常。 TypeInitializerException僅僅意味着從構造函數中拋出異常。從QuestionGenerator.GetNextQuestion()的調用中包含的代碼會生成異常。

+0

InnerException:System.NullReferenceException HResult = -2147467261 消息=未將對象引用設置爲對象的實例。 源= WebTracing 堆棧跟蹤: 在UltooAgent.QuestionGenerator..cctor()在C:\用戶\拉傑夫\桌面\跟蹤\跟蹤\跟蹤\ WebTracing \ WebTracing \ QuestionGenerator.cs:線12 的InnerException: – Rajeev