【问题标题】:(AccessViolationException was unhandled) How do i implement HandleProcessCorruptedStateExceptions in C#?(AccessViolationException 未处理)如何在 C# 中实现 HandleProcessCorruptedStateExceptions?
【发布时间】:2019-05-13 03:04:18
【问题描述】:

在我运行程序大约一天后,我遇到了一个问题,即 AccessViolationException 未处理。

(更多信息:我使用的是 Visual Studio 2010)

但是,它没有说明此异常发生的位置,给了我两个选项,即“确定”和“继续”。当我按下确定时,什么也没发生,所以我按下继续,程序停止调试。

当我试图找到解决方案时,我明白我可以实施HandleProcessCorruptedStateExceptions 来解决这个问题。但是,我不知道从哪里开始。

我是否只包含以下代码?我在哪里包含这些代码?

[HandleProcessCorruptedStateExceptions] 
[SecurityCritical]
public static int Main() 
{ 
   try
     {
       // Catch any exceptions leaking out of the program CallMainProgramLoop(); 
     }
   catch (Exception e) 
       // We could be catching anything here 
     {
         // The exception we caught could have been a program error
        // or something much more serious. Regardless, we know that
        // something is not right. We'll just output the exception 
       // and exit with an error. We won't try to do any work when
       // the program or process is in an unknown state!

        System.Console.WriteLine(e.Message); 
        return 1; 
     } 

  return 0; 

}

或者,我也可以这样做legacyCorruptedStateExceptionsPolicy,但它说我应该在配置文件中输入所需的语句。我在哪里可以找到配置文件?

感谢所有回复!

【问题讨论】:

  • 你说“我运行我的程序大约一天”然后“我按下继续并且程序停止调试” - 是吗意思是你在 Visual Studio 调试器中运行你的程序好几天?
  • @vasily.sib 是的,我目前正在为一家公司做一个项目,它需要运行几天的程序。但是这个异常导致它停止,所以我被告知要修复它。我正在使用 Visual Studio 2010。
  • 看看this question。此外,请注意,Visual Studio 2010 已于 2015 年结束生命周期(并将在明年达到延长支持的结束日期)。
  • @vasily.sib 非常感谢您的帮助。我知道我必须实现另一篇文章中所述的代码,但我只是创建函数而已吗?我必须在我的代码中的某个地方调用它吗?我很抱歉提出多余的问题,因为程序再次运行,所以我无法修改代码。我只是想先澄清一下,一旦异常再次出现,我可以立即更改它。

标签: c# visual-studio error-handling


【解决方案1】:

你的问题的实际答案是here,我真的不应该再回答了,但我想给你看一些代码示例,我不想在评论中写它:)

在我的一个项目中,不时出现不可预知的异常。为了抓住它,我在Program.cs 中编写了这段代码:

[STAThread]
static void Main()
{
    // add UnhandledException handler
    AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MainForm());
}

private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
    // prepare message for user
    var message = "There was an unknown exception while running <app_name>!";
    var exception = e.ExceptionObject as Exception;

    if (exception != null)
    {
        // change message if there was actual exception
        message = $"There was an {exception.GetType().Name} exception while running <app_name>! {exception.Message}";
        // adding inner exceptions messages
        var innerException = exception.InnerException;
        while (innerException != null)
        {
            message += $"\r\n-> {innerException.GetType().Name}: {innerException.Message}";
            innerException = innerException.InnerException;
        }
#if DEBUG
        // add tracing info
        message += $"\r\n\r\n{GetStackTrace(exception)}";
#endif
    }
    if (e.IsTerminating) message += "\r\n\r\n<app_name> will be closed.";

    // showing message to the user
    MessageBox.Show(message, "Unhandled Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
#if DEBUG
private static string GetStackTrace(Exception exception)
{
    var trace = new System.Diagnostics.StackTrace(exception, fNeedFileInfo: true);
    var frames = trace.GetFrames()
        .Select((f, i) => {
            var filename = f.GetFileName();
            var methodInfo = f.GetMethod();

            var frame = $"#{i} in the method {methodInfo.DeclaringType.FullName}.{methodInfo.Name}()";
            if (filename != null) frame += $" (source file: {System.IO.Path.GetFileName(filename)}@{f.GetFileLineNumber()}:{f.GetFileColumnNumber()})";

            return frame;
        });

    return $"Full stack trace ({trace.FrameCount} frames total):\r\n{string.Join("\r\n", frames)}";
}
#endif

现在,当发生未处理的异常时 - 将出现一个消息框,显示完整的异常消息(和内部异常消息)。对于 Debug 构建还有一个完整的堆栈跟踪,其中包含方法名称、行号和发生异常的源文件名。

关于 HandleProcessCorruptedStateExceptions

您在评论中提到了 HandleProcessCorruptedStateExceptions 属性。 The docs 明确表示,除非您绝对确定自己需要它,否则不应使用它。

损坏的进程状态异常是表示 进程的状态已损坏。我们不推荐 在此状态下执行您的应用程序。

默认情况下,公共语言运行时 (CLR) 不提供这些 托管代码和try/catch 块(和其他 异常处理子句)不会为它们调用。 如果你是 绝对确定您希望继续处理这些 例外,您必须应用 HandleProcessCorruptedStateExceptionsAttribute 方法的属性 您要执行其异常处理子句。 CLR 提供 适用异常子句的损坏进程状态异常 仅在同时具有 HandleProcessCorruptedStateExceptionsAttributeSecurityCriticalAttribute attributes.

损坏的进程状态意味着发生了一些真正灾难性的事情,并且您的应用现在死机更安全。如果你还不够害怕,这里是上面示例中的Main() 方法,其中设置了HandleProcessCorruptedStateExceptions 属性:

[STAThread]
[HandleProcessCorruptedStateExceptions, SecurityCritical]
static void Main()
{
    try
    {
        // add UnhandledException handler
        // AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
        // * in this particular case is not quite useful to handle this exceptions,
        //   because you already wrap your entire application in a try/catch block

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }
    catch (Exception ex)
    {
        // handle it somehow
    }
}

【讨论】:

  • 非常感谢!我的经理要求我创建一个日志文件来跟踪错误,并在我进行研究之前回答它。非常感谢您会在我的程序开始出现错误后尝试一下!
  • 当我尝试将您的代码输入到一个新文件中时,它在这些行上显示错误消息 += $"\r\n-> {innerException.GetType().Name}: {innerException.信息}”; and message = $"There was an {exception.GetType().Name} exception while running !{exception.Message}";但是当我尝试删除 $ 时,它可以工作。可以去掉吗?很抱歉提出这些问题。
  • 我猜这是因为 VS 2010 无法处理字符串插值。只需将其替换为普通的string.Format()
  • 还有一个问题,非常抱歉。如果我要尝试实现上面提到的 HandleProcessCorruptedStateExceptions 代码。我应该在哪里输入这些代码?在 Form1.cs 或 Program.cs 内?
  • 非常感谢您回答我的问题!欣赏它。
猜你喜欢
  • 1970-01-01
  • 2017-02-27
  • 1970-01-01
  • 2020-07-24
  • 2012-07-06
  • 1970-01-01
相关资源
最近更新 更多