How to handle unhandled exceptions in a C# program [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm writing a program on C# and I'm just starting on using Exception. I've done Java before but I tried to avoid exception at any cost. I understand now that I can't avoid it any longer. So I need some advice. I have a code like this:
try
{
//...
}
catch
{
//...
}
//...
try
{
//...
}
catch
{
//...
}
This is a GUI program. I want to make it so that if an exception is caught, the program will basically stop all operation and but not close the program, so the GUI is still there, users can make changes to the problem found.
BTW: Our lecturer will fail us for multiple returns, so that advice won't do

You can define a handler to catch all unhandled exceptions. The exact mechanism depends on the UI framework you are using.
For WinForms you can do something like
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// Windows forms exceptions handler
Application.ThreadException += new
ThreadExceptionEventHandler(Application_ThreadException);
http://kenneththorman.blogspot.com/2010/10/windows-forms-net-handling-unhandled.html
For WPF you would do something like
<Application x:Class="UnhandledExceptionHandler.App"
DispatcherUnhandledException="Application_DispatcherUnhandledException">
</Application>
private void Application_DispatcherUnhandledException(object sender,
System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
// Handle the exception
}
http://www.codeproject.com/Articles/90866/Unhandled-Exception-Handler-For-WPF-Applications

Just in case Eric J.'s answer is too involved:
I assume since your prof will only permit one return statement that you will have something like a service that does some work and notifies the caller of the status and possibly an error message.
If you can get by with boolean messages, then the following should work for you:
public class Service
{
public bool DoWork()
{
bool success = false;
try
{
//code to do work
success = true;
}
catch(Exception ex)
{
//do something with the ex
success = false;
}
return success;
}
}

Related

Replacing Obsolete Closing Eventargs with new FormClosing args [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
We are currently in the process of updating our database system and all of the files by building them(32bit-2005 VC#) to 64 bit now. Something I've come across is the leaking of data when an assignment using this.closing += new CancelEventArgs(Event Name); I've found it to be obsolete as fellow colleagues have put it and am looking for a way to switch to using the FormClosing event.
...
Old Code and Event Ex.
this.Closing += new CancelEventHandler(AssignUsers_Closing);
private void AssignUsers_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
"some event"
}
catch (Exception ex)
{
ShowException se = new ShowException();
se.ShowDialog(ex);
}
}
This is where I'd like to convert to the FormClosing Event so that windows can take care of the data leak for me rather than having to add a -= statement for each event like this to the .dispose() function.
Idea/New Code
private void AssignUserForm_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
*code*
// Use e.cancel to test whether to close the form or not.
}
catch (Exception ex)
{
ShowException se = new ShowException();
se.ShowDialog(ex);
}
}
Would this be a viable alternative. Any suggestions on how to make this change?
EDIT: BETTER OVERVIEW OF MY QUESTION
Changing this:
public AssignUserForm()
{
InitializeComponent();
InitMe();
try
{
Database.ApplyFieldSecurity(this);
}
catch { }
}
private void InitMe()
{
try
{
this.Closing += new CancelEventHandler(AssignUsers_Closing);
// Get the users from the system
//Binding happens
}
catch (Exception ex)
{
throw ex;
}
}
Turning it into something where I can use Windows Events to simply create a FormClosing event.
The problems were solved. There was a data leak occurring between our database and when the control that this dialog belonged to were loading. I appreciate all of the help. The database shot over the information before the dialog loaded, and then would send it over again. Only one set of the data was properly disposed of. We fixed the problem. Thank you. –

How to use BackgroundWorker in winform c# [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
i'm new to winform and i can't figure out how to use the BackgroundWorker.
basically what i'm trying to do is this:
i have 1 form with 2 buttons: "Import" and "Exit" . when calling ImporButton_Click all it does is creates an HttpListener and listen to a given URL. ExitButton_Click closes the form.
the problem is when i press "Import" the form get stuck and it's in "not responding" status until someone is calling the listener and free it.
i'm trying to under stand how BackgroundWorker can help me to overcome that "stuck" problem. i don't understand how to invoke the backgroundWorker1_DoWork method
Here is my code so far:
//Program.cs
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new ConfigurationForm());
}
}
//ConfigurationForm.cs
public partial class ConfigurationForm : Form
{
public ConfigurationForm()
{
InitializeComponent();
UrlTextBox.Text = #"enter URL here";
}
private void ImporButton_Click(object sender, EventArgs e)
{
try
{
String urlToListen = UrlTextBox.Text;
//Invoke MyListener
MyListener.StartListen(urlToListen); //assume this is implemented
}
catch (Exception exception)
{
string errorMsg = String.Format("An exception occured = {0}", exception);
MessageBox.Show(errorMsg);
}
}
private void ExitButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
}
}
so, what now ? how do i invoke the backgroundWorker1_DoWork ???
10x to anyone who can help
You need to call this method RunWorkerAsync
backgroundWorker1.RunWorkerAsync();
If you want to pass some argument into the handler DoWork via the DoWorkEventArgs, try the second overload of RunWorkerAsync:
backgroundWorker1.RunWorkerAsync(yourArgument);

How can I trust in 'lock' anymore?

back on my old unmanaged c++ days, I could trust in my critical sections in a multithreading application. So, now with dotNet/C#, I was relaying on the lock mechanism. By locking a resource I was confident any thread couldn't access those resources within my piece of code.
This seems not to be true in dotNet!
I have my windows service application. I create a main managed thread with an hidden Form hosting a third parity OCX. Within this thread I do message pumping an polling on a list of objects. This list of objects gets modified by events fired by the OCX within this managed thread.
I post simplified parts of my code here:
public bool Start()
{
ServiceIsRunning = true;
m_TaskThread = new Thread(new ParameterizedThreadStart(TaskLoop));
m_TaskThread.SetApartmentState(ApartmentState.STA);
m_TaskThread.Start(this);
return true;
}
private void OnOCXEvent(object objToAdd)
{
lock(m_ObjectList)
{
m_ObjectList.Add(objToAdd); }
}
}
private void CheckList()
{
lock(m_ObjectList)
{
foreach(object obj in m_ObjectList)
{
...
}
}
}
[STAThread] // OCX requirement!
private void TaskLoop(object startParam)
{
try {
...
while (ServiceIsRunning)
{
// Message pump
Application.DoEvents();
if (checkTimeout.IsElapsed(true))
{
CheckList();
}
// Relax process CPU time!
Thread.Sleep(10);
}
} catch(Exception ex) {
...
}
}
You won't beleve me: I got a 'list has been modified' exception in CheckList! 8-/
So I did some logging and I noticed that the OnOCXEvent will be raised when the SAME managed thread is within the CheckList foreach loop. I'm sure: I got the same managed thread id in my log file, the foreach loop wasn't finished and the OnOCXEvent has been called by the same manged thread!
Now I'm wondering: how can this happen? Is a single managed thread implemented with more win32 threads?
Hope someone can explain why this is happening, so I can solve this issue.
Thanks,
Fabio
My Note:
I actually solved the issue creating a copy of the list before the foreach loop. But I do not like this solution. I also like to understand what is happening. I do not own the third parity OCX code, but the method I call within the CheckList loop has logically nothing to do with the OCX event beening fired.
I strongly suspect this is just a re-entrancy issue.
Within your CheckList call you're calling an OCX method. If that does anything which can itself raise OCX events - including effectively calling Application.DoEvents - then you can end up with OnOCXEvent being called in a thread which is also executing CheckList... and that will cause the problem.
This isn't an issue with lock - it's an issue with re-entrancy.
One way to diagnose this would be to modify your CheckList and OnOCXEvent methods:
private bool inCheckList;
private void OnOCXEvent(object objToAdd)
{
lock(m_ObjectList)
{
if (inCheckList)
{
throw new Exception("Look at this stack trace!");
}
m_ObjectList.Add(objToAdd);
}
}
private void CheckList()
{
lock(m_ObjectList)
{
inCheckList = true;
foreach(object obj in m_ObjectList)
{
...
}
inCheckList = false; // Put this in a finally block if you really want
}
}
I strongly suspect you'll see the exception thrown with a stack trace which includes CheckList, OnOCXEvent - and a bunch of code in-between, with something that runs the message loop in the middle.

How to avoid error message window

we're having an application on server instance and quite rarely, but we have out of memory exception (program is not leaking, just instance is quite small and it operates with quite big amounts of data).
That would be not a problem, as we monitor processes on that server instance and if some of the processes are not found in process list, alert email is sent.
Now the problem is with this:
That prevents process from disappearing from process list, so we don't get alert email about it's failure. Is it possible to disable this message, that if program fails on something we don't catch, it would close without user interaction?
Assuming Windows Forms, I typically do multiple steps to prevent this message box.
First, I connect several handlers in the Main function:
[STAThread]
private static void Main()
{
Application.ThreadException +=
application_ThreadException;
Application.SetUnhandledExceptionMode(
UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException +=
currentDomain_UnhandledException;
Application.Run(new MainForm());
}
Those handlers are being called when an otherwise unhandled exception occurs. I would define them something like:
private static void application_ThreadException(
object sender,
ThreadExceptionEventArgs e)
{
doHandleException(e.Exception);
}
private static void currentDomain_UnhandledException(
object sender,
UnhandledExceptionEventArgs e)
{
doHandleException(e.ExceptionObject as Exception);
}
The actual doHandleException function that is then called does the actual error handling. Usually this is logging the error and notifying the user, giving him the options to continue the application or quit it.
An example from a real-world application looks like:
private static void doHandleException(
Exception e)
{
try
{
Log.Instance.ErrorException(#"Exception.", e);
}
catch (Exception x)
{
Trace.WriteLine(string.Format(
#"Error during exception logging: '{0}'.", x.Message));
}
var form = Form.ActiveForm;
if (form == null)
{
MessageBox.Show(buildMessage(e),
"MyApp", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show(form, buildMessage(e),
"MyApp", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
With the helper function:
public static string buildMessage(Exception exception)
{
var result = new StringBuilder();
while (exception != null)
{
result.AppendLine(exception.Message);
result.AppendLine();
exception = exception.InnerException;
}
return result.ToString().Trim();
}
If you are using not Windows Forms but e.g. a Console application or WPF, some handlers are not present, while others are present instead.
The idea stays the same: Subscribe to event handlers that are being called if you have no try...catch around your code blocks.
Personally, I try to have as few of those try...catch blocks as possible (ideally none).
don't know if you can deactivate this - but I think you should not.
Find the bug/problem in your application and handle the problem with a craceful shutdown or by preventing the problem in first case.
Everything else will be a real crude workaround and I don't think your client will be pleased to have such a behavior (after all won't there be data lost? If not this has allways the buggy / not finished touch)
You could put a global try/catch block in your program and exit the program on any unexpected exception.
If using WPF you can try-catch the following two exceptions in your app.xaml.cs. There may be other/complementary exceptions to handle, but this are the two I am usually looking for:
AppDomain.CurrentDomain.UnhandledException - "This event provides notification of uncaught exceptions. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application. If sufficient information about the state of the application is available, other actions may be undertaken — such as saving program data for later recovery. Caution is advised, because program data can become corrupted when exceptions are not handled."
Dispatcher.UnhandledException - "Occurs when a thread exception is thrown and uncaught during execution of a delegate by way of Invoke or BeginInvoke."
ie:
public partial class App : Application
{
public App()
{
this.Dispatcher.UnhandledException += DispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
}
private void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// log and close gracefully
}
private new void DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
e.Handled = true;
// log and close gracefully
}
}

Unhandled Exceptions from Managed C# User Control used in MFC Dialog

Our core application is built in MFC C++, but we are trying to write new code in .NET, and have created a User Control in .NET, which will be used on an existing MFC Dialog.
However, when a unexpected/unhandled exception is thrown from the User Control, it causes the MFC app to crash (illegal op style), with no ability to recover.
I've added
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
To the Constructor of the .NET user control, but it doesn't seem to catch anything.
Is there any way to add an event in MFC to handle these?
Quick google didn't return anything useful.
Thanks.
Edit: Still haven't been able to resolve this the way I'd like, looks like the best way to do it, is try and catch around all the .NET code, so no exceptions bubble up.
I asked this same question a while ago: Final managed exception handler in a mixed native/managed executable?
What I have found is that the managed unhandled exception events ONLY fire when running in a managed thread. The managed WndProc is where the magic happens.
You have a few options: you could place a low-level override in CWinApp and catch Exception^. This could have unintended side-effects. Or, you could go with Structured Exception Handling (SEH) which will give you a hack at /all/ unhandled exceptions. This is not an easy road.
I think you want to have the unhandled exception handler in the MFC side of things:
AppDomain::CurrentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(&CurrentDomain_UnhandledException);
[same for Application.ThreadException]
Have a look at this similar question on the MSDN forums: Unhandled Exception in Mixed Mode application
Of course, the better idea would be either to handle the exception in the C# code, or else to find out what's causing it, and fix it so that the exception is never thrown. What's preventing that?
In every event handler of the user control, place a try/catch block:
private void btnOk_Click(object sender, EventArgs e) {
try {
// real code here
}
catch (Exception ex) {
LogException(ex);
// do whatever you must in order to shut down the control, maybe just
}
}
Here's what I use:
public static class UI
{
public static void PerformUIAction(Control form, Action action)
{
PerformUIAction(form, action, (string) null);
}
public static void PerformUIAction(
Control form, Action action, string message)
{
PerformUIAction(form, action, () => message);
}
public static void PerformUIAction(
Control form, Action action, Func<string> messageHandler)
{
var saveCursor = form.Cursor;
form.Cursor = Cursors.WaitCursor;
try
{
action();
}
catch (Exception ex)
{
MessageBox.Show(
messageHandler() ?? ex.Message, "Exception!",
MessageBoxButtons.OK, MessageBoxIcon.Error,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
Debug.WriteLine(ex.ToString(), "Exception");
throw;
}
finally
{
form.Cursor = saveCursor;
}
}
}
I call it like this:
private void _copyButton_Click(object sender, EventArgs e)
{
UI.PerformUIAction(
this, () =>
{
// Your code here
});
}
I added the unhandled exception handler to the constructor of the .NET user control
I don't think that will work; I believe the exception handler has to be setup before a call to Application.Run. Do you have any Application.Run calls in your app?
How about something like this on the MFC side of things before you initialize any .NET controls:
Application.SetUnhandledExceptionMode(System.Windows.Forms.UnhandledExceptionMode.CatchException);
Application.ThreadException += ...;
See if the ThreadException handler is called.

Categories