Reputation: 2864
I have a winforms application.Winforms start with Program.cs where we have main() defined.I have put this code in try-catch block.
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmSplash());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
if (ex.InnerException != null)
{
MessageBox.Show(ex.InnerException.ToString());
}
}
}
Whenever there is a win32 exception,this mechanism fails and unhandled exception message is thrown and application crashes.
I have 2 questions regarding this code:
1) Why win32 exceptions are not caught.
2) Is it a good practice to catch exceptions at the highest level.
Upvotes: 14
Views: 13389
Reputation: 8339
Try subscribing to these events before your application starts (Application.Run
) :
You could then get rid of your try catch
block.
I think it is bad practice to catch exceptions at the highest level, but you cannot avoid it ! During development (Debug), those exceptions should not be caught and the application should do the nastiest thing possible (crash ?). In production (Release), you will want your application to degrade as nicely as possible even when unhandled exceptions occur. This is one of the few uses I found for the DEBUG
preprocessor variable.
Upvotes: 2
Reputation: 8339
EDIT : as Pratik pointed out, the following answer applies to .NET 1.0 and .NET 1.1 only. Starting with .NET 2.0, non-CLS exception should be caught as a RuntimeWrappedException.
Because Win32 exceptions do not derive from the .NET Exception class. Try :
try {
} catch (Exception ex) {
// .NET exception
} catch {
// native exception
}
See Catch non-CLSCompliant exceptions in general handlers for more information.
Upvotes: 17
Reputation: 31071
1) Win32 exceptions should be caught. Maybe the exception is being thrown from a background thread or the GC thread?
2) It depends on your app structure. For example, if your error notification UI was tied to the main form somehow (e.g. you need to invoke the UI thread from a worker thread), then it would be silly to display a UI in a code block outside the code that runs the message loop. However, if your code example is single-threaded then it would be fine.
Upvotes: 0
Reputation: 11074
While I don't know why your catch block doesn't work try using the Application ThreadException Event. This should catch any error in application threads. Add an event handler before calling Application.Run.
For your second answer definitely yes. I develop and maintain a enterprise winforms application that talk with a web service backend on background threads. If any webservice call crashes handle the application threadexception (and also appdomain unhandledexception) event, log and popup an error that business users can report and allow them to continue without crashing the application.
Upvotes: 3
Reputation: 4410
You may need to catch as Win32Exception (or ExternalException) instead
http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx
I seem to remember that Win32Exception inherits from ExternalException but ExternalException does not inherit from Exception so won't be caught by your code.
Edit: See other answers for why this is wrong!
Edit 2: As for the second part, as stated by AnthonyWJones It is good manners to let the user know that a problem has caused the application to close, however I would recommend using a plain English statement to the user, and logging the exception stack to a log file for your own use.
Upvotes: 0
Reputation: 189505
The execution of Application.Run is not throwing an error. That is happening on another thread (or at least asynchronously).
Its good idea to inform the user in friendly way that the application has failed before it disapears completely, however its not a good idea to just catch then continue.
Upvotes: 3