Can C # WinForm static void Main NOT catching Exception?

I have a WinForm application written in C# where I put a try-catch in Program.cs , in the program record, the static void Main method, right at the beginning of the application, for example:

 using System; using System.IO; using System.Windows.Forms; namespace T5ShortestTime { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new T5ShortestTimeForm()); } catch (Exception e) { string errordir = Path.Combine(Application.StartupPath, "errorlog"); string errorlog = Path.Combine(errordir, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".txt"); if (!Directory.Exists(errordir)) Directory.CreateDirectory(errordir); File.WriteAllText(errorlog, e.ToString()); } } } } 

As you can see, Application is placed in a try-catch and in a catch , the only thing it does is create an error log file.

Now, so far so good. My application works well, and if I encounter a crash, the last Exception should be caught by the try-catch and stored in the error log file.

However, when I run my program for a while, I get a null reference exception. What surprises me is that the exception does not create an error log file.

Now this post shows that this is possibly caused by a ThreadException or HandleProcessCorruptedStateExceptions (the two most important answers), but in my case a simple null is shown The original exception:

 Problem signature: Problem Event Name: CLR20r3 Problem Signature 01: T5ShortestTime.exe Problem Signature 02: 2.8.3.1 Problem Signature 03: 5743e646 Problem Signature 04: T5ShortestTime Problem Signature 05: 2.8.3.1 Problem Signature 06: 5743e646 Problem Signature 07: 182 Problem Signature 08: 1b Problem Signature 09: System.NullReferenceException OS Version: 6.3.9600.2.0.0.272.7 Locale ID: 1033 Additional Information 1: bb91 Additional Information 2: bb91a371df830534902ec94577ebb4a3 Additional Information 3: aba1 Additional Information 4: aba1ed7202d796d19b974eec93d89ec2 Read our privacy statement online: http://go.microsoft.com/fwlink/?linkid=280262 If the online privacy statement is not available, please read our privacy statement offline: C:\Windows\system32\en-US\erofflps.txt 

Why should it be?

+7
c # exception winforms
source share
3 answers

the last exception should be caught by a try-catch block

That will not happen. Except for one case when you run your program with an attached debugger. Thus, you are probably bogged down in the hope that this will work, everyone always starts their program with F5 for a while.

Application.Run () has a breakback in its code that raises events, try / catch-em-all, which raises the Application.ThreadException event when the event handler throws an unhandled exception. This reverse stop is really necessary, especially in the x64 version of Windows 7. Very bad things happen when there is no exception handler. However, when you start the debugger, this reverse does not work, which makes unhandled exceptions too difficult to debug.

So, when you are debugging, your catch clause will be executed. Unhandled exceptions are too difficult to debug. When you run without a debugger, your catch clause will not run, and your program will crash, as you described. Throwing an unhandled exception is too difficult to debug.

So don’t do it like that. How Application.Run () handles unhandled exceptions is configured using the Application.SetUnhandledExceptionMode () method. You will like this version better:

  [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if (!System.Diagnostics.Debugger.IsAttached) { Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); AppDomain.CurrentDomain.UnhandledException += LogException; } Application.Run(new Form1()); } private static void LogException(object sender, UnhandledExceptionEventArgs e) { string errordir = Path.Combine(Application.StartupPath, "errorlog"); string errorlog = Path.Combine(errordir, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".txt"); if (!Directory.Exists(errordir)) Directory.CreateDirectory(errordir); File.WriteAllText(errorlog, e.ToString()); AppDomain.CurrentDomain.UnhandledException -= LogException; MessageBox.Show("Error details recorded in " + errorlog, "Unexpected error"); Environment.Exit(1); } 

With this code, you can easily debug unhandled exceptions. The Debugger.IsAttached test ensures that the debugger always stops when the event handler crashes. Without a debugger, it fires the Application.ThreadException event (which is completely useless) and prefers to listen to all exceptions. Including those that were raised in workflows.

You must warn the user so that the window does not just disappear without a trace. I was going to recommend MessageBox, but noticed that this error is now re-enabled in Windows 10. Sigh.

+5
source share

ThreadException not an exception type like ( NullReferenceException ). It:

This event allows your Windows Forms application to handle otherwise unhandled exceptions that occur in Windows Forms threads.

This means that it handles exceptions in threads other than the main thread.

So, you need to subscribe to: AppDomain.CurrentDomain.UnhandledException also to handle exceptions in the main topic (regardless of the type of exception, for example NullReference , IndexOutOfRange , etc.).

+2
source share

Ok, at the end I will implement Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException) as shown by Hans Passant for VB.Net in this post . Here I posted my own code + error log for C# :

 static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if (!System.Diagnostics.Debugger.IsAttached) { Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); AppDomain.CurrentDomain.UnhandledException += LogUnhandledExceptions; } Application.Run(new T5ShortestTimeForm()); } private static void LogUnhandledExceptions(object sender, UnhandledExceptionEventArgs e) { Exception ex = (Exception)e.ExceptionObject; string errordir = Path.Combine(Application.StartupPath, "errorlog"); string errorlog = Path.Combine(errordir, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".txt"); if (!Directory.Exists(errordir)) Directory.CreateDirectory(errordir); File.WriteAllText(errorlog, ex.ToString()); Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex)); } 

Furthermore, it seems that the source of confusion here is that there are actually two common Exceptions happening:

The first of these was any Exception from the application itself:

 System.Exception: Exception of type 'System.Exception' was thrown. at T5ShortestTime.T5ShortestTimeForm..ctor() in C:\Test.cs:line 45 at T5ShortestTime.Program.Main() in C:\Test.cs:line 19 at ... 

And the second happens during the Dispose of the Form components, which creates another exception, and this null reference exception:

 System.NullReferenceException: Object reference not set to an instance of an object. at T5ShortestTime.T5ShortestTimeForm.Dispose(Boolean disposing) at System.ComponentModel.Component.Finalize() 

So, when I test the exception in my application, the NullReferenceException comes last, in Dispose .

enter image description here

I only managed to capture this after I set UnhandledExceptionMode to ThrowException above.

+2
source share

All Articles