簡體   English   中英

無法捕獲FormClosing中拋出的異常

[英]Can't catch exception thrown in FormClosing

當FormClosing中拋出異常時,我無法用正常的try / catch來捕獲它 - 為什么不呢?

例:

  public partial class Form2 : Form
  {
    public Form2() { InitializeComponent(); }

    protected override void OnClosing(CancelEventArgs e)
    {
      base.OnClosing(e);
      throw new Exception("lets catch this");
    }
  }

我嘗試像這樣抓住它:

  try
  {
    var f = new Form2();
    f.ShowDialog();
  }
  catch (Exception ex)
  { 
    //this is never hit!
    MessageBox.Show("try/catch: " + ex);
  }

拋出異常,從未在我的try / catch中捕獲。

但是,我可以使用Application.ThreadException += ..來捕獲它Application.ThreadException += ..但此時很難恢復。

我能做什么?

此外:
我使用的是Windows8 x64 - 該程序的目標是x86
我在這里發現了一個問題,但我的例外並不是沉默。

更新1
當我附加到進程時,它會像我剛剛手動啟動.exe文件一樣失敗: 在此輸入圖像描述

這是預期的行為。

ShowDialog方法不應拋出事件拋出的異常。 你正在做的也是錯誤的做法。 您在OnClosing上的OnClosing 應該是安全的,不會拋出任何錯誤。 如果不是這種情況,它將作為UnhandledException傳遞。

可以捕獲異常,但是您應該在OnClosing處理程序中執行此操作。

protected override void OnClosing(CancelEventArgs e)
{
  base.OnClosing(e);
  try {
    throw new Exception("lets catch this");
  }
  catch (Exception e) {
    // Do something with e
  }
}

剝離此行為的代碼如下所示:

  try
  {
    FormClosingEventArgs e1 = new FormClosingEventArgs(this.closeReason, false);
    this.OnClosing((CancelEventArgs) e1);
    this.OnFormClosing(e1);
  }
  catch (Exception ex)
  {
    Application.OnThreadException(ex);
  }

您的問題的解決方案可能是這樣的:

public partial class Form2 : Form
{
    // I'm using the event here, but if this class in turn is a base for another class, you might as well override the method. (Event will still work, since events allow multiple handlers when using the default event handlers.)
    private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        try
        {
            // Action that might throw an exception
            throw new Exception("Some exception");
        }
        catch (Exception ex)
        {
            OnClosingException = ex;
        }
    }

    public Exception OnClosingException { get; protected set; }
}

// When calling
var f = new Form2();
f.ShowDialog();
if (f.OnClosingException != null) // Re-throw the exception wrapped in another exception that describes the problem best
    throw new InvalidOperationException("Some message", f.OnClosingException); // Might not always be InvalidOperationException
// Instead of re-throwing you can also just handle the exception

如果這是你計划在很多場景中使用的東西,你可能想要為它創建一個接口,以一種很好的結構化方式包裝它。 對於一次性場景我不會打擾。

暫無
暫無

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

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