Exceptions and WinForms

G

Guest

It appears that exception handling outside of a form corrupts winforms.

If we have two forms say form1 and form2. On form1 (our start form) I've put
a button click event which does a showdialog() for form2. In this click event
I've got a try catch around the showdialog method. On form2 I've added a
button and a click event which deliberately throws an exception. When the
exception is thrown in form2 the code correctly arrives back at the catch in
form1. Any subsequent calls to showdialog() then fails with no exceptions
thrown.

Any Ideas
 
D

Daniel Moth

Do you recreate the form before calling ShowDialog again? Show some code

Cheers
Daniel
 
G

Guest

Hi Daniel.
Thanks for replying.

Below is some example code.

private void Form1_KeyPress(object sender,
System.Windows.Forms.KeyPressEventArgs e)
{

Form2 frm2;

if(e.KeyChar == 'A' || e.KeyChar =='a' )
{
frm2 = new Form2();

try
{
frm2.ShowDialog();
}
catch(Exception)
{
//MessageBox.Show("Form2 through exception" + Ex.Message);
}
finally
{
frm2.Dispose();
frm2=null;

}


frm2 = new Form2();

try
{
frm2.ShowDialog();
}
finally
{
frm2.Dispose();
frm2 = null;
}
}

Form2 Key presss event

private void Form2_KeyPress(object sender,
System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar == 'A' || e.KeyChar =='a')
throw new Exception("From2 exception");

}
 
D

Daniel Moth

Does this happen only when you are debugging? In other words, try the same
app that exhibits the problem by manually launching it on the device without
VS attached and see if the dialog stays up with no secondary exception.

Cheers
Daniel
 
G

Guest

Hi Daniel.
No, this happens with and without the debugger.
The full framework works correctly.
 
D

Daniel Moth

Stepping back and looking at your original question, actually, I'd say that
is expected behaviour. Any exception handling should be done within a form
and not allowed to propagate outside of it (to ShowDialog origin or
otherwise).

So the only thing left to examine is whether there is an incompatibility
with the desktop. Can you try your full framework version of the app built
in Release mode, run from the file system and without VS attached?

Cheers
Daniel
 
G

Guest

Hi Daniel.
Running the full framework in release mode does throw a messagebox saying
that an unexpected exception has been thrown.

Are we suggesting that try/catch statements only work within a form in
winforms applications ?
If so, are we also suggesting we need to put try/catch statements around
every method to stop an exception propagating back. Is there another stragegy
to catch form level exceptions ?
 
D

Daniel Moth

Regardless of platform, you should trap exceptions (of the specific types in
fact) at places where you expect to get them.

On the full framework you can also apply global exception handling but again
this is mostly used for logging purposes and not for actual handling. On CF
1.0 GEH is not possible so you really must trap them where you expect them
to occur. CF 2.0 will support GEH (in a slightly different way to the
desktop).

For more on the GEH approach see my blog entries
Desktop:
http://www.danielmoth.com/Blog/2004/08/global-exception-handling-net-v11-part.html
http://www.danielmoth.com/Blog/2004/08/global-exception-handling-net-v20-cf.html

CF 1.0:
http://www.danielmoth.com/Blog/2004/08/global-exception-handling-net-cf-v10.html

CF 2.0:
http://www.danielmoth.com/Blog/2004/12/appdomainunhandledexception-part-1.html
http://www.danielmoth.com/Blog/2004/12/appdomainunhandledexception-part-2.html

So to repeat the answer: Add try..catch blocks wherever you are expecting an
exception to be thrown.

Cheers
Daniel
 
G

Guest

Hi Daniel.
Thanks. I may not like the answer but at least I have one.

One of the reasons for using exceptions in the first place is to deal with
the unexpected. We don't always know when an exception will be thrown.
Catching at the top process level (one central point) gives me and the user
an opportunity to try the process again. Are we ever going to get away from,
forms dictating strategy.
 
D

Daniel Moth

Well, I wouldn't paint such a bad picture. It is very unfortunate that CF
1.0 does not have GEH, but CF 2.0 has so that is good.

Having said that, if you are trying to literally handle an exception (i.e.
try to recover from it) then you must do it at the place where it occurred.
It is there where you have the context of the exception including state and
the stack. If you look at the help (F1) for each method of the framework
you'll see the exceptions that it throws and under what circumstances. You
should do the same for your own methods (and 3rd parties too). Effectively,
whenever you make a call you should satisfy the preconditions of the method
and then you'll never get an exception. Now, some methods/scenarios execute
in more open contexts hence the possibility of an exception can never be
avoided; it is only in those cases where you have to explicitly catch the
exception and, again, the documentation helps you.

GEH is there for bugs (you should have handled it but you didn't so while
debugging this helps) or for traceability (rather than get the built in
dialog, you can put your own up and log the exception details somewhere).

Cheers
Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top