为什么我的应用程序在发布模式下崩溃而在调试模式下没有?

8

发布模式和调试模式有什么区别?

如何在发布模式下进行调试以查看故障情况?

class Program
{
    [STAThread]
    static void Main()
    {
        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainWindow());
        }
        catch (Exception ex)
        {
            Logger.Error("Main : "+ex.Message, typeof(Program));
            MessageBox.Show(ex.Message + ex.StackTrace);
            Environment.Exit(1);
        }
    }
}
5个回答

9
你的代码片段中的catch子句在应用程序的发布版本中将永远无法捕获任何内容。但是,在附加了调试器的情况下运行它确实有效。
你错过了Application.ThreadException的工作原理。每当检测到未处理的异常时,该事件都会触发。但是,当您调试代码时,此功能未启用。没有安装异常处理程序以引发此事件。这是为了让您有一个良好的方法来调试未处理的异常。你的代码更改了这种行为,现在有一个try块处于活动状态,你的catch处理程序获取该异常。
要使代码以相同的方式运行,您需要更改未处理的异常处理策略。像这样:
    [STAThread]
    static void Main() {
        try {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
            Application.Run(new Form1());
        }
        catch (Exception ex) {
            // etc..
        }
    }

现在你的捕获子句将始终捕获异常。只要它在主线程上引发,它就不会捕获在工作线程中引发的异常。考虑改用以下代码进行统一处理:

    [STAThread]
    static void Main() {
        AppDomain.CurrentDomain.UnhandledException += AllUnhandledExceptions;
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
        Application.Run(new Form1());
    }

    private static void AllUnhandledExceptions(object sender, UnhandledExceptionEventArgs e) {
        var ex = (Exception)e.ExceptionObject;
        // Display or log ex.ToString()
        //...
        Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex));
    }

3

我的经验告诉我,你应该寻找处理任何设置的代码。

你可以从没有在注册表中设置和应用程序配置文件中设置的情况下,调试你的应用程序开始。

如果你的应用程序使用数据库,你也应该尝试使用一个空数据库。

第二步是在你同事的计算机上调试你的应用程序。

希望这能帮助你的探索。


同意。对我来说,损坏的设置文件通常是原因。搜索并删除与此应用程序相关的user.config文件。 - narmaps

2

很多原因可能会导致这种情况发生,许多专业人员可以确认这是任何应用程序的经典错误,在您确信一切正常时,在客户机上却无法工作。

在没有提供任何异常详细信息的情况下,很难说为什么会发生这种情况。

顺便说一句,您可以通过从Visual Studio附加到应用程序来调试它。

如何:附加到正在运行的进程


谢谢您的回答,但是您能解释一下为什么我的代码甚至不能捕获这个异常吗?它只是崩溃了,没有异常、消息框或任何东西。 - armin
@armin,事件查看器显示了什么? - L.B
1
有些类型的异常无法通过 try/catch 捕获,例如 StackOverflow。像 L.B 建议的那样查看 EventViewer,或者启用 First Chance Exceptions 来查看发生了什么以及在哪里发生了异常。 - Tigran
@armin:你是在另一台机器上以发布模式运行还是在你开发的同一台机器上运行? - Tigran
同一台机器,还有,我能否只发布调试模式的程序集? - armin
显示剩余2条评论

0

调试模式和发布模式是构建代码的两种不同方式。由于使用的每个开发环境的具体方法都不同,因此无法立即确定。模式也可能被称为Mode1&Mode2。

然而,您的调试模式可能会在二进制文件中编译调试信息(符号表,行编号等),而发布模式则不会。但可能存在成千上万的差异。

尝试找到指定Debug / Release模式的位置,您将找到区别!


0

找到任何环境选项的最佳方法是记录生产过程中发生的情况。首先捕获和记录异常,然后利用所学知识进行更具体的日志记录。

请参阅此Microsoft kb文章以获取说明。

至于发布和调试模式背后的思想:

发布模式和调试模式存在的目的是允许不同的配置,一个旨在帮助开发人员查找错误,另一个则是为了优化性能,并为生产环境进行配置。

学习区别的最佳方法就是打开项目生成属性(右键单击项目,选择“属性”,然后单击左侧的“生成”选项卡)。查看可以根据配置更改的所有不同选项。

调试与发布的另一个常见问题是未正确设置一个项目项(例如配置文件或嵌入式资源)上的生成操作


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接