3

我有從文本文件讀取數據的應用程序。最近我意識到我應該爲文本文件中的數據創建數據檢查器,以查看我是否可以正確顯示/處理它。不拋出異常(在Win7中)

基本上目前所有的檢查器都會看到數據的格式是否正確,即double是雙精度型,int是int等等。如果不是,我拋出一個異常。

像這樣:

private static string CheckDouble(string doublevar) 
     { 
      double tryParseDoubleResult; 
      var tryParseDouble = double.TryParse(doublevar, out tryParseDoubleResult); 

      if (tryParseDouble) 
      { 
       return doublevar; 
      } 

      throw new Exception("Invalid data found. Cannot open."); 
     } 

這將是巨大的。除了以下:

  • 我建立了這個在Win 7環境VS 2008
  • 我在Win7/XP下測試
  • 當在Win7運行 - 對異常不會拋出。我甚至可以看到它應該有,因爲我顯示它加載到應用程序中的列表框中的數據,但加載後列表爲空。如果我一行一行地查看有錯誤數據的項目,我可以看到異常拋出。但是,如果不是逐行調試,而不是在調試版本中,則不在調試中。
  • 在XP中,異常將按預期方式拋出。

這顯然是其在有問題的數據,但沒有跡象顯示用戶狀態的應用程序運行的問題,它不應該讓用戶走到這一步,如果有與數據有問題。

爲什麼不是在Win7中拋出異常?


編輯:

我想,也許是異常被吞噬,因爲我只看到一行行通過加強時,它拋出。檢查是否被吞嚥的最好方法是什麼?只需按照我的應用程序執行並尋找Try塊? (當它在XP中已經正確拋出時,它仍然不完全有意義,但是...)

作爲一個額外的,我有一個啓動窗口3按鈕。一個是打開按鈕。從這裏我打開數據文件進行處理。

var w = new Window1(); 
w.Show(); 

//此時,所有的TabItems的FormLoad內窗口1執行,在異常應該拋出。事實上,當它發生時,什麼也沒有拋出,但是執行從異常應該拋出的行跳轉到Close()下面的行。並且下一個窗口加載,但三個中的一個屏幕是空的,因爲由於數據而拋出異常。

Close(); 

EDIT1:

在拋出異常是單身,我不知道這有什麼有問題的類...

編輯2:

經過幾天的進一步調查,我仍然在失去爲什麼這是幸福效果圖創作。解決問題:是的,我知道我應該製作自己的自定義異常類。但這並沒有改變這裏發生的事情。我找不到更高的籌碼。我有一個異常處理程序,如果在應用程序中拋出異常,它將Environment.Exit(1);然後將異常記錄到文本文件中。我已經將異常處理程序完全取出,但仍然看到相同的行爲。

這是不是由於區域設置的問題...

不管怎樣,拋開一切,這還不能解釋爲什麼按預期在XP中的異常被拋出(和應用程序崩潰和日誌例外文件)而在Win7中 - 這個異常被忽略並繼續執行。

+0

爲什麼不直接使用'double.Parse'這將引發它自己的異常?但是,必須有別的東西吞噬異常,因爲您發佈的代碼沒有任何問題。 – 2010-06-24 01:25:41

+0

@Dean,他使用tryParse()的事實不是問題。我同意,其他事情正在引發一個問題。 – BobbyShaftoe 2010-06-24 01:27:13

+0

你能給我們一個輸入的例子,它被錯誤地解析爲'double'嗎? – 2010-06-24 01:28:30

回答

2

首先,你真的應該扔你自己有例外。 System.Exception是所有異常繼承的頂級異常。考慮創建一個DataFormatException,例如 - 並拋出它。

接下來,它聽起來像您很可能捕獲System.Exception中的某人在吞噬此異常的堆棧中較低。同樣,如果您僅在該線程的堆棧中的最低點捕獲System.Exception,並將其用作整個應用程序的捕獲所有者,那將是理想的。在代碼的其他地方,你應該捕捉預期會發生的異常。例如,你的方法的調用者應該只是試圖捕獲DataFormatException和ArgumentException(如果「doublevar」爲null或空,你應該拋出它)。例如:

/// <summary> 
/// Checks to see if the specified value is a double. 
/// </summary> 
/// <param name="valueToCheck">The value to check.</param> 
/// <exception cref="ArgumentException">If <paramref name="valueToCheck"/> 
/// is null or empty.</exception> 
/// <exception cref="DataFormatException">If <paramref name="valueToCheck"/> 
/// could not be parsed as a valid double.</exception> 
private static double CheckDouble(string valueToCheck) 
{ 
    if (string.IsNullOrEmpty(valueToCheck)) 
     throw new ArgumentException("Argument 'valueToCheck' cannot be null or empty.", "valueToCheck"); 

    double result; 

    if (double.TryParse(valueToCheck, out result)) 
    { 
     return result; 
    } 

    throw new DataFormatException("Value '" + valueToCheck + "' could not be parsed as a double."); 
} 

希望幫助...

+0

謝謝你的回答。不過,我想知道,異常可以被吞噬的唯一方法是通過進入棧的某個地方的'try {}'塊。會不會有另一種情況會導致異常被吞噬? – baron 2010-06-24 05:33:03

+0

@baron - 不是真的。發生異常時,它會「落入」堆棧,直到它找到合適的catch塊,或者它碰到最後一個(最下面的)堆棧幀 - 這是應用程序崩潰時出現未處理的異常。在callstack中必須有人捕獲System.Exception – 2010-06-24 06:01:37

+0

AFAICT - 事實並非如此。我不是100%確定異常處理程序,但如果我完全評論,同樣的事情發生,所以我不知道爲什麼這會被吞噬,並且只在這個環境中! – baron 2010-06-28 04:24:06

0

您的計算機最有可能在區域設置上有所不同。例如,千位/十進制分隔符在國家之間有所不同,例如「1,000.00」與「1.000,00」,DateTime格式不同等等。嘗試使用明確指定CultureInfo的Parse/TryParse/ToString重載並避免默認計算機的設置,或許使用CultureInfo.InvariantCulture

1

我假設你在這裏使用tryparse並重新拋出異常只是爲了演示try分析不能按預期工作......爲什麼不嘗試在你內部添加一個Debug.Print就是if語句來查看你是什麼獲得。

此外,確保該代碼是不是從一個包裝這個代碼與被吞嚥異常

1

當你在調試模式下踩着通過try/catch塊的另一個函數調用,您可以看到拋出的異常,對吧?那之後會發生什麼?也就是說,在throw new Exception()行之後,當你按下F10時,最終會出現在哪裏?這是異常被吞噬的地方。

如果您在框架代碼結束的地方,這意味着你需要手動添加一個try ... catch自己在處理該文件中的代碼:

void Form_Load(object sender, EventArgs e) 
{ 
    try 
    { 
     ParseFile(); 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show("The file was not valid: " + ex.Message); 
    } 
} 
+0

查看編輯,打到F10後,我在'w.Show();'後面沒有Try Try Catch塊這個 – baron 2010-06-28 03:45:25