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