我遇到了一个问题,即在我运行程序约一天后,AccessViolationException未得到处理。
(更多信息:我正在使用Visual Studio 2010)
但是,它没有说明发生此异常的位置,给了我两个选择,分别是“确定”和“继续”。当我按OK时,什么也没发生,所以我按了继续,程序停止了调试。
当我尝试找到解决方案时,我了解到可以实施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,但是它说我应该在配置文件中输入所需的语句。在哪里可以找到配置文件?
感谢所有回复!
答案 0 :(得分:0)
问题的实际答案是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
现在,当发生未处理的异常时-将出现一个消息框,其中显示完整的异常消息(和内部异常消息)。对于调试构建,还有完整的堆栈跟踪,其中包含发生异常的方法名称,行号和源文件名。
您在评论中提到了HandleProcessCorruptedStateExceptions
属性。 The docs明确指出,除非绝对确定需要使用,否则不要使用它。
损坏的流程状态异常是表明以下情况的异常: 进程状态已损坏。我们不推荐 在这种状态下执行您的应用程序。
默认情况下,公共语言运行库(CLR)不会提供这些 托管代码和
try/catch
块(以及其他 不会为它们调用异常处理子句)。 如果您是 绝对确定,您要保持对这些内容的处理 例外情况,您必须应用 方法的HandleProcessCorruptedStateExceptionsAttribute
属性 要执行其异常处理子句。 CLR提供 适用的异常条款的损坏的流程状态异常 仅在同时具有HandleProcessCorruptedStateExceptionsAttribute
和SecurityCriticalAttribute 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
}
}