c# continue in main handled exception [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I continue running after an unhandled exception?
I've seen tons of similar questions and anwsers on SO, but not the same.
I'm handling all uncaught exception in main like this:
In Main I set following:
Application.ThreadException += new ThreadExceptionEventHandler(MainForm_UIThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new MainForm());
If I run my programm in debugger, after the exception occured and I handled them in MainForm_UIThreadException or CurrentDomain_UnhandledException, the yellow debugger arrow points to the line, where this exception actually occured, so I can step over, which means (for me) that execution context isn't lost.
I know that I cant continue execution for unhandled exceptions, but this esception is actually handled, just somewhere else.
Is it possible to continue execution of current function?
Thank you

You don't. When you get an AppDomain unhandled exception, your app is
no longer in a stable state. Where exactly would you resume to? When
you've gotten to that point, your only option, with good reason, is to
exit. You could reasonably schedule yourself to run again to make sure
the app comes back, but a far better idea is to actually handle the
exception at its source and prevent it from being an
UnhandledException.
From: How do I continue running after an unhandled exception?

In a WinForms application, if you want to continue running, you need to handle exceptions in your UI event handlers.
For example:
private void saveButton_Click(object sender, EventArgs e)
{
try
{
... call BLL to save data
}
catch(Exception ex)
{
MessageBox.Show("Failed to save data");
}
}

Related

C# WPF unhandled exception: how to make the most of it

I am quite new to WPF but find AMAZING to be able to trap any unhandled exception. I have put
this.Dispatcher.UnhandledException += Dispatcher_UnhandledException;
in the constructor of my class. This leads me to trap it with
private void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true;
...
}
At first it didn't work but then I've seen that to make it work I have to run it in release and outside VS IDE. So that works.
What I'd like is to get as much as info as possible about what caused the exception. Possibly the exception type, the s/r, the line and whatever else is provided.
At the moment by doing
int a = 0;
int b = 3 / a;
and by putting
MessageBox.Show(e.ToString() + " " + sender.ToString());
I get:
so that's not the right way.
I know that I am not putting the necessary information in the question but I have searched through various answer but none reported what I need. If so it can be useful to save any data prior closing but not about closing but not to detected what caused the exception
What's more when I exit with
Environment.Exit(-1)
I find the process still running and that's a problem.
Here Terminate application after unhandled exception it says that I have to kill my process is it really the right way to close my application after an unhandled exception?
Thanks for any help
The actual exception that caused the application to crash is wrapped inside the DispatcherUnhandledExceptionEventArgs parameter.
Simply use e.Exception to get hold of it.
MessageBox.Show(e.Exception.ToString());
After displaying the exception, I would suggest allowing the application to continue by calling the base method:
base.OnUnhandledException(sender, e);
You may choose to mark the exception as handled of course, however in the case of when you are simply overriding this method to display the error, I would not count that as handled.

Global level error handling in C# windows application

I am trying to implement global level error handling in my windows application
I have the button click event for the form which creates some error
label1.Text =
class1.Calculate(Convert.ToSingle(textBox1.Text), Convert.ToSingle(textBox2.Text))
.ToString(CultureInfo.InvariantCulture);
MessageBox.Show("That was really Close");
now I want the control to go to message box, the unhandled error are being handled in the main function as
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
}
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
if (e.Exception.InnerException != null)
MessageBox.Show(e.Exception.InnerException.Message.ToString());
else MessageBox.Show(e.Exception.ToString());
}
This code sample does handles the exception but I want the control back to the button Click, that is The MessageBox.Show("That was really Close"); should get called after exception handling
If you don't want the method to stop on an exception then you need to handle the exception at that point. You could have the catch call some kind of global error handling method but you will need a try catch in that method.
Global level exception handling is for exceptions that you can't deal with immediately and need to catch before the program dies, usually for logging and such like.
Global level exception handling is not a substitute for handling exceptions at the correct place. If you expect code to throw an exception and it is one you can deal with then you should put a try/catch at that point of the code. In the example above you say you want to carry on running the method so clearly the error is not a fatal one so you should deal with it in the normal way.
Often though it should be noted that exceptions that you can handle are ones that can be avoided. For example checking what you pass to a method before passing it. The ones that can't be removed entirely are usually ones to do with external resources (eg reading files). I'm sure there are a lot of other exceptions but as somebody wise once said "Exceptions are for exceptional circumstances". If you can foresee them you should try to avoid them.
In this case I assume the exception is related to invalid input in your text boxes. In this case you should use Single.TryParse to verify the input before passing it on to your method. If either of the values fails to parse you can then let the user know that properly.

How to quit application in AppDomain.CurrentDomain.UnhandledException handler and still ensure that finally{} blocks execute?

I wish to prevent "application has stopped working" popup from appearing whenever an exception occurs. One way to do this is obviously calling Environment.Exit(1) in a global exception handler, i.e. AppDomain.CurrentDomain.UnhandledException like this:
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception exc = (Exception)e.ExceptionObject;
Console.Error.WriteLine("Exception:\n{0}", exc.Message);
Console.Error.WriteLine("Stack trace:\n{0}", exc.StackTrace);
Environment.Exit(1); // quit silently on exception, don't show the popup
}
However, the above code results in finally blocks not executing due to the order of execution. A simple example of such behavior:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
try
{
Console.WriteLine("try block");
throw new Exception("Somebody set us up the bomb.");
}
catch
{
Console.Error.WriteLine("catch block");
throw;
}
finally
{
Console.WriteLine("finally block");
}
Environment.Exit(1) in the exception handler results in this output (notice no finally block) before application quits:
try block
catch block
Exception:
Somebody set us up the bomb.
Stack trace:
at ...
This can cause serious problems when it is critical that finally block executes, e.g. when cleaning up temp files created inside try.
Is there a simple way around all this? That is, keep global exception handler, customize exception output etc. inside it and and then exit gracefully, but still get finally blocks to execute. I find it weird that this problem has not been mentioned in questions like this.
You are not going to get this. Environment.Exit() ensures that finalizers still run, that could be the fallback. But not for cleaning up temporary files, use the operating system support for that and use the FileOptions.DeleteOnClose option.
In general you should never rely on a hard requirement for cleanup, nothing is getting cleaned-up when the CLR bombs with SOE or FEEE, the user terminates you app from Task Manager, hard-reboots the machine or the power goes off.

How to ensure saving of application state on crash c#

I am very new to c# programming, so that in mind:
I have an in-memory data object with data I need to save the information when(if) my application were to crash OR closed. Is there a way to do this deterministically or reliably?
I have been looking at destructors
~MyObjectName(){}
finalizers and Dispose(),
but as far as I understand none of these will do reliably what I want?
Currently I am using the destructor, and it works when I am closing the program, but this doesn't mean it will work on crashing, or always.
Should I be looking at events as well?
There is no 100% reliable mechanism that you can use to save data (or do anything else for that matter) when a process (any process, not just a .Net process) terminates - most processes can be terminated at any point using the "End Process" option in the task manager, when this happens the process is immediately killed. As a more extreme example the power cord could be pulled out the back of the machine.
If its not 100% necessary that this data object be up-to-date and saved once the process is killed then the AppDomain.UnhandledException Event may suffice.
If its absolutely 100% necessary that this be the case then you need to be continuously saving this information as the process is running - there is absolutely no guarentee that you will get a chance to do it at a later date. This is how databases operate, no transaction returns until some record of the change has been recorded to disk in some format (e.g. a transaction log). This is what the D stands for in ACID.
I believe you are looking for catching unhandled exceptions? something like this:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
// here you can log the exception ...
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
// here you can log the exception ...
}
This example shows how to manage all exceptions that haven't been
caught in the try-catch sections (in Windows Forms application).
The UnhandledException event handles uncaught exceptions thrown from
the main UI thread. The ThreadException event handles uncaught
exceptions thrown from non-UI threads.
You can achieve this with windbg.
Keep a breakpoint in zwterminateprocess method in windbg. This method will be called when your application exits.
when the breakpoint is reached , use !dumpheap -type MyObjectName to get the address of your object
Use !dumpobject "address of MyObjectName" to know the values inside the object

Catching exception in Main() method

Consider the following simple application: a windows form created by a "new C# windows application" sequence in VS that was modified in a following way:
public static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show("An unexpected exception was caught.");
}
}
Form1.cs contains the following modifications:
private void Form1_Load(object sender, EventArgs e)
{
throw new Exception("Error");
}
If I press F5 in IDE, then, as I expect, I see a message box saying that exception was caught and the application quits.
If I go to Debug(or Release)/bin and launch the executable, I see the standard "Unhandled exception" window, meaning that my exception handler doesn't work.
Obviously, that has something to do with exception being thrown from a different thread that Application.Run is called from. But the question remains - why the behavior differs depending on whether the application has been run from IDE or from command line?
What is the best practice to ensure that no exceptions remain unhandled in the application?
Normally Application.ThreadException will handle the exception in the Load event. You'll get the ThreadExceptionDialog that offers the Quit and Continue options.
But not when a debugger is attached. The catch clause in the message loop that displays the dialog is intentionally disabled in that case. That's necessary because it would be very difficult to trouble-shoot exceptions if that dialog pops up when you debug a program. Which this catcher no longer active, your catch clause in the Main() method now gets a shot at the exception.
You can make it consistent by using Application.SetUnhandledExceptionMode() in the Main() method. You shouldn't, exceptions really are hard to debug if you do this. If you want to customize exception handling for the UI thread then you should register your own Application.ThreadException handler:
if (!System.Diagnostics.Debugger.IsAttached)
Application.ThreadException += myThreadException;
Trapping unhandled exceptions in worker threads requires a AppDomain.UnhandledException handler. They are not recoverable.
Also beware of a bug in 64-bit Windows, exceptions in the Load event are swallowed without diagnostic when a debugger is attached. Force AnyCPU mode to avoid that trap.
In addition to catching any exceptions thrown inside the Main method you must also handle AppDomain.CurrentDomain.UnhandledException and Application.ThreadException.
Not sure why the behavior differs with and without a debugger attached though.

Categories