(AccessViolationException было необработанным) Как я могу реализовать HandleProcessCorruptedStateExceptions в C #? - PullRequest
0 голосов
/ 13 мая 2019

Я столкнулся с проблемой, что 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 , но он говорит, что я должен ввести требуемый оператор в файле конфигурации. Где я могу найти файл конфигурации?

Ценю все ответы!

1 Ответ

0 голосов
/ 13 мая 2019

Фактический ответ на ваш вопрос: здесь , и я действительно не должен отвечать на него снова, но я хочу показать вам некоторый пример кода и не хочу писать его в комментарии:)

В одном из моих проектов время от времени возникало непредсказуемое исключение. Чтобы поймать это я пишу этот код в 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 build с именем метода, номером строки и исходным именем файла, где происходит исключение.

О HandleProcessCorruptedStateExceptions

Вы упомянули атрибут HandleProcessCorruptedStateExceptions в своем комментарии. В документах четко сказано, что вы не должны использовать его, если вы абсолютно не уверены, что вам это нужно.

Поврежденные исключения состояния процесса - это исключения, которые указывают на то, что состояние процесса было повреждено. Мы не рекомендуем выполнение вашего заявления в этом состоянии.

По умолчанию общеязыковая среда выполнения (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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...