簡體   English   中英

如何讓WinForms靜靜地忽略未處理的異常?

[英]How can I get WinForms to stop silently ignoring unhandled exceptions?

這變得非常惱人。 現在我有一個winforms應用程序,但事情沒有正常工作,但據我所知,沒有例外。 在逐步完成幾乎所有相關代碼之后,事實證明在我的應用程序開始時拋出異常。

簡而言之,在WinForms中,如果出現異常,WinForms庫會忽略它。 沒有“發生未處理的異常”拋出JIT消息,它只是停止處理當前事件並返回GUI。

這會導致隨機錯誤,因為在加載此數據之前發生異常,因此未調用加載數據的代碼。

為了看到這一點,我創建了一個全新的WinForms應用程序,並輸入以下代碼:

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

    private void Form1_Load(object sender, EventArgs e)
    {
        string blah = null;
        blah.Trim();
    }
}

按F5並加載表單而不顯示任何錯誤,即使正在拋出空引用。

然后我嘗試轉到我的Program.cs主方法並添加Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 它。 仍然我的表單加載而不會導致任何錯誤被拋出。

即使我知道我可以告訴VS打破所有異常,我發現這種情況非常糟糕。 它導致了很難在生產中調試的奇怪問題,因為這是一個內部工具,我真的很想擁有它,所以當異常發生時它實際上會出錯,而不是默默地忽略它。

有誰知道如何做到這一點?


更新:只是為了更新我從評論中學到的東西。

這似乎是一個64位的Windows問題,正如我從這個問題中學到的,我在發布之前沒有看到。 在那個問題中,它指出了一個關於此的微軟錯誤報告 ,其中有這樣的說法:

你好,

此錯誤已關閉為“外部”,因為此行為是由x64版本的Windows處理異常引起的。 當用戶模式異常穿過內核轉換時,x64版本的Windows不允許異常傳播。 因此,附加的調試器不知道發生異常的事實導致調試器未能在未處理的異常上中斷。

不幸的是,Visual Studo團隊無法解決這個問題,這是操作系統設計的結果。 有關此問題的所有反饋都應提交給Windows團隊; 但Windows團隊認為這是“正確的”操作系統設計,並認為x86行為“不正確”。

最誠摯的問候,Visual Studio Debugger

話雖這么說,如果在Program.cs有以下代碼,那么構建不通過visual studio(或使用Ctrl + F5運行)似乎確實顯示了JIT異常消息框EXCEPT

 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 

該代碼將導致窗口忽略該異常。

但是,如果您(而不是)訂閱Application.ThreadException事件,不僅會捕獲您的異常,Visual Studio的調試器在未處理的異常中中斷!

在Program.cs的主要功能中,您還應確保已打包調用以在try / catch中打開表單。 另外,使用AppDomain.UnhandledException來捕獲異常。 我們也添加了Application.ThreadException

我相信以下內容將為您提供可以拋出的所有異常的鈎子...

static void Main()
{
    try
    {
        System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(OnGuiUnhandedException);
        AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

        var form = new MainForm();
        form.ShowDialog();
    }
    catch (Exception e)
    {
        HandleUnhandledException(e);
    }
    finally
    {
        // Do stuff
    }
}

private static void HandleUnhandledException(Object o)
{
    // TODO: Log it!
    Exception e = o as Exception;

    if (e != null)
    {

    }
}

private static void OnUnhandledException(Object sender, UnhandledExceptionEventArgs e)
{
    HandleUnhandledException(e.ExceptionObject);
}

private static void OnGuiUnhandedException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    HandleUnhandledException(e.Exception);
}

請嘗試以下方法。

這是代碼片段:

[STAThread]
public static void Main(string[] args)
{
    try
    {
        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        //your program entry point
    }
    catch (Exception ex)
    {
       //manage also these exceptions
    }
}

private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
    ProcessException(e.Exception);
}

一個簡單的解決方法是不在調試器下運行。

由於某種原因,調試器正在屏蔽異常。 如果您正常運行您的應用程序(Ctrl + F5),您將得到通常的“應用程序中發生未處理的異常...繼續/退出?” 對話。

經歷過這種情況並確定了有關64位操作系統和Form.Load事件的問題后,我總是在Form.Shown事件中完成所有啟動功能。 出於所有實際目的,這是相同的事情(除了一些罕見的特殊情況),並且JIT消息在Shown事件中產生。

暫無
暫無

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

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