簡體   English   中英

c#winform文本框驗證未處理的異常

[英]c# winform textbox Validating unhandled exception

我對“文本框驗證”事件有疑問。 當被觸發時,如果拋出異常,則不會返回到try catch塊。

try
{
   new form().showdialog();
}
catch(exception e)
{
   console.writeline("ok");
}

那么就留在這里,不要被抓住:

private void TB_Validating(object sender, CancelEventArgs e)
{
   throw new Exception("aaa");
}

相反,這會在捕獲代碼上顯示錯誤

private void TB_Click(object sender, CancelEventArgs e)
{
   throw new Exception("aaa");
}

誰能建議我原因和解決方案?

“為什么”是一個漫長而痛苦的故事 ,無法很好地滿足SO的答案。 黃金法則是,異常絕不能導致調度程序循環終止。 您可以通過調用Application.Run()來使調度程序循環進行循環,如在Main()入口點中所做的那樣,或通過Form.ShowDialog()像本代碼片段中那樣進行。 正是這種循環確保了ShowDialog()在關閉對話框之前不會返回。

Winforms通過在調度程序循環中使用try / catch-em-all語句來遵守該規則。 如果事件處理程序引發異常,它將引發Application.ThreadException事件。 如果您不替換(或禁用)事件處理程序(應該這樣做),那么您將看到ThreadExceptionDialog,它使用戶可以在“ Continue”上進行賭博或明智地單擊“ Quit”。

但是,在調試時,這種萬能的處理程序非常不方便。 它妨礙了診斷未處理的異常。 因此,Winforms會檢查是否進行調試以及是否進行調試,否則將使用try / catch-em-all並不會引發ThreadException事件。 這對您代碼段中的代碼有很大的副作用,現在catch語句似乎確實可以正常工作。 但是,只要您按照用戶的方式運行程序,而無需調試器,它就不會捕獲任何東西。

所以冷酷的事實是,在事件處理程序中引發異常只是錯誤的事情。 除了笨拙的ThreadExceptionDialog之外,沒有其他人可以抓住它。 而不是拋出,您必須執行異常處理程序將執行的操作。 對於應該為ErrorProvider的Validating事件,給用戶一個溫和的提示,即他的數據輸入不正確。 或將e.Cancel = true設置為強制他輸入有效數據。

在窗體的ShowDialog方法內部未調用事件處理程序TextBoxValidating 而是從GUI線程消息泵中調用它(您可以在https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows中找到Windows消息泵的基本描述)。 這就是為什么您無法在代碼中捕獲它的原因(因為您的代碼未調用該方法)。

您可以在此處處理異常:

  Application.ThreadException += ... 

我不知道為什么從ShowDialog消息思想內部調用Button Click處理程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM