Throwing exception in a try block?

K

Kevin Yu

John

"No, it is not a good idea to wrap everything in a try/catch block. Don't
use try/catch unless you have a real reason to catch an exception or
cleanup
(finally). What does the catch do? If it just rethrows the exception,
then
you're wasting your effort, making your code hard to read and not adding
any
value."

In the catch block, the error will be log to the windows event log, then the
exception
is wrapped into a custom exception and rethrown. not sure if this is a good
idea.

There are different type of exception, if it's application critical input
parameters such
as those read from the application config file/console input (console app
called by
windows service by spawning a process and pass parameters), if those values
are incorrect or corrupted which
are unlikely, then an exception should be thrown to stop the execution. with
the throwing
exception in the try catch block, it will easy stop the application whenever
a parameter
is incorrect. I mean using goto or continue statement will do but in terms
of handling the situation,
I think throwing exception will make more sense.

so in this case, do this:

try
{
if (error)
throw new exception("Error");
}
catch (Exception ex)
{
Logerror();
}


won't be so bad.
 
H

Helge Jensen

Kevin said:
In the catch block, the error will be log to the windows event log, then the
exception

Okay, that's reasonable... if you expect the caller to just die or
mishandle the exception.
is wrapped into a custom exception and rethrown. not sure if this is a good
idea.

Now *that*'s my favorite hate-thing on exceptions!

What does wrapping it help the caller? Logging certainly didn't produce
any additional information the caller would like to have.

More importantly, you have robbed the caller of the possibility to catch
the exception by type, just use:

catch ( Exception e ) {
Log(e);
throw;
}

(As you may be able to tell, this is not my first discussion on the
subject :)
try
{
if (error)
throw new exception("Error");
}
catch (Exception ex)
{
Logerror();
}

I really don't like that, it's just a very complicated way of doing
goto, and there are better options: write one logging handler at the
call-stack top, and then use exceptions to signal errors, knowing that
someone will catch, log, and whatever they feel is approrpriate.

static int _Main(string args[]) {
// just code along, and throw INFORMATIONAL errors
// if anything goes wrong.
if ( error )
throw new ParsingException(
string.Format("Invalid argument {0}", arg))
// ...
return 0;
}

static int Main(string args[]) {
#if !DEBUG
try {
#endif
return _Main(args);
#if !DEBUG
} catch ( Exception e ) {
Log(e);
throw;
#endif
}

The (#if !DEBUG) allows you to use the "break if not catched" setting in
the IDE usefully. You could use another symbol, DEBUG is just *so* handy
for me :)

This pattern is also pretty usefull when testing:

void Test() {
string[] valid_args = { "x" };
string[] invalid_args = { "y" };

AssertEquals(_Main(valid_args), 0);

ParseException threw = null;
try {
_Main(invalid_args);
} catch ( ParseException e ) {
threw = e;
}
AssertNull(ParseException);
}
 
M

Mohammad

Helge said:
Retrying an operation, for example:

- When a protocol over an unreliable media comes out of sync.
- When a modem dial-up fails
- When a user can be asked to enter another possibility

Touché :)
Which is a kind of "else-if-by-error".

This kind of "recovery-by-default" is usually not a good idea (atleast
in the long run) since it removes the possibility of the caller noticing
that the default was chosen instead of the selected value (which was
misspelled and thus gave a parse-error).

Well, in this particular case, it would have been great if the
framework contained a sort of "CanParse" function. So instead of
calling Int32.Parse and bracing for the exception to hit, I would have
preferred to call Int32.CanParse and THEN do some action.
Well,... yes -- but sometimes components wish to keep separate logs of
unexpected errors
Touché again.
 
D

David Levine

Well, in this particular case, it would have been great if the
framework contained a sort of "CanParse" function. So instead of
calling Int32.Parse and bracing for the exception to hit, I would have
preferred to call Int32.CanParse and THEN do some action.

There is ...

double.TryParse() and there are arguments that let you specify the data
type.

Whidbey has more methods besides that one.
 
D

David Levine

What does wrapping it help the caller? Logging certainly didn't produce
any additional information the caller would like to have.

More importantly, you have robbed the caller of the possibility to catch
the exception by type, just use:

catch ( Exception e ) {
Log(e);
throw;
}

Except that in v1.1 using a naked throw causes the stack trace to get reset,
so you lose that information.

I prefer to catch-wrap-throw, as nothing is lost and you can add context
information. I use a helper method to
rethrow the original exception type, as in...

catch(Exception ex)
{
throw CloneException("Context info.",ex);
}

This preserves the original exception type, the stack trace info, and adds
additional meaning.
I really don't like that, it's just a very complicated way of doing goto,
and there are better options: write one logging handler at the call-stack
top, and then use exceptions to signal errors, knowing that someone will
catch, log, and whatever they feel is approrpriate.

I prefer a log twice option, the first time at the original site where the
exception was caught, and once again at the top. The reason is to catch code
paths where an exception is inadvertently swallowed on its way up the call
stack. This can be a problem in a large project with many different
components written by different developers - no one person has personal
knowledge of every piece of code in the system.
 
H

Helge Jensen

David said:
Except that in v1.1 using a naked throw causes the stack trace to get reset,
so you lose that information.

Yes, that's a bug. But the original trace is in the log, that's why you
did the catch, so it's not that bad.
I prefer to catch-wrap-throw, as nothing is lost and you can add context
information. I use a helper method to
rethrow the original exception type, as in...

catch(Exception ex)
{
throw CloneException("Context info.",ex);
}

That's not really wrapping, is it? That's working around the
"throw;"-bug. At least if you really are "cloning" ex.

A nice workaround :)
This preserves the original exception type, the stack trace info,
yes.

and adds
additional meaning.

Only if the "Context info" doesn't shadow the information in ex, but is
made available on enquery.

It's a nice trick though, It (in effect) allows adding notes to an
exception in the form of objects not available at the error-site, but
non-theless important to understanding the error as the exception
bubbles the call-stack.
I prefer a log twice option, the first time at the original site where the
exception was caught, and once again at the top. The reason is to catch code
paths where an exception is inadvertently swallowed on its way up the call
stack. This can be a problem in a large project with many different
components written by different developers - no one person has personal
knowledge of every piece of code in the system.

I recognize this problem, people writing:

try {
f();
} catch {};

should get a *very* serious talking-to.

But how does the above help you with that?

It must be a very involved logfile-analysis to extract the relevant
information, especially since there is nothing that warns you this may
be the problem. The program explicitly *doesn't* terminate.

How do you skip all the places where actual error-handling is done?
 
J

Jay B. Harlow [MVP - Outlook]

David,
| I prefer a log twice option, the first time at the original site where the
| exception was caught, and once again at the top. The reason is to catch
code
Have you looked at the new .NET 2.0 AppDomain events pertaining to
Exceptions?

http://msdn2.microsoft.com/library/1dw188c1.aspx

Such as CatchingException & ExceptionThrown. I have not tried it, reading
about ExceptionThrown, it sounds like it may allow one to log the exception
at the original site, instead of splattering your code with a lot of Catch
blocks...

I would be curious on your take on the exceptions after you have had a
chance to use them.

Just a thought
Jay


|
| >
| > What does wrapping it help the caller? Logging certainly didn't produce
| > any additional information the caller would like to have.
| >
| > More importantly, you have robbed the caller of the possibility to catch
| > the exception by type, just use:
| >
| > catch ( Exception e ) {
| > Log(e);
| > throw;
| > }
| >
|
| Except that in v1.1 using a naked throw causes the stack trace to get
reset,
| so you lose that information.
|
| I prefer to catch-wrap-throw, as nothing is lost and you can add context
| information. I use a helper method to
| rethrow the original exception type, as in...
|
| catch(Exception ex)
| {
| throw CloneException("Context info.",ex);
| }
|
| This preserves the original exception type, the stack trace info, and adds
| additional meaning.
|
| >
| > I really don't like that, it's just a very complicated way of doing
goto,
| > and there are better options: write one logging handler at the
call-stack
| > top, and then use exceptions to signal errors, knowing that someone will
| > catch, log, and whatever they feel is approrpriate.
|
| I prefer a log twice option, the first time at the original site where the
| exception was caught, and once again at the top. The reason is to catch
code
| paths where an exception is inadvertently swallowed on its way up the call
| stack. This can be a problem in a large project with many different
| components written by different developers - no one person has personal
| knowledge of every piece of code in the system.
|
|
|
|
|
 
K

Kevin Yu

Helge Jensen said:
Okay, that's reasonable... if you expect the caller to just die or
mishandle the exception.


Now *that*'s my favorite hate-thing on exceptions!

What does wrapping it help the caller? Logging certainly didn't produce
any additional information the caller would like to have.


well, I think the purpose of making a custom exception is to include more
information for the exception,
sometimes, people want to log and error source such as the machine name or
IP, information like that.
and use the original exception as inner exception.




More importantly, you have robbed the caller of the possibility to catch
the exception by type, just use:

catch ( Exception e ) {
Log(e);
throw;
}

(As you may be able to tell, this is not my first discussion on the
subject :)
try
{
if (error)
throw new exception("Error");
}
catch (Exception ex)
{
Logerror();
}

I really don't like that, it's just a very complicated way of doing
goto, and there are better options: write one logging handler at the
call-stack top, and then use exceptions to signal errors, knowing that
someone will catch, log, and whatever they feel is approrpriate.

static int _Main(string args[]) {
// just code along, and throw INFORMATIONAL errors
// if anything goes wrong.
if ( error )
throw new ParsingException(
string.Format("Invalid argument {0}", arg))
// ...
return 0;
}

static int Main(string args[]) {
#if !DEBUG
try {
#endif
return _Main(args);
#if !DEBUG
} catch ( Exception e ) {
Log(e);
throw;
#endif
}

The (#if !DEBUG) allows you to use the "break if not catched" setting in
the IDE usefully. You could use another symbol, DEBUG is just *so* handy
for me :)

This pattern is also pretty usefull when testing:

void Test() {
string[] valid_args = { "x" };
string[] invalid_args = { "y" };

AssertEquals(_Main(valid_args), 0);

ParseException threw = null;
try {
_Main(invalid_args);
} catch ( ParseException e ) {
threw = e;
}
AssertNull(ParseException);
}

--
Helge Jensen
mailto:[email protected]
sip:[email protected]
-=> Sebastian cover-music: http://ungdomshus.nu <=-
 
K

Kevin Yu

I really don't like that, it's just a very complicated way of doing
goto, and there are better options: write one logging handler at the
call-stack top, and then use exceptions to signal errors, knowing that
someone will catch, log, and whatever they feel is approrpriate.


I don't know if it's a bug or not, in a timer_elapsed event handler, if an
exception occur,
it won't bubble back to the caller, since it's running in another thread, so
if there is
no try catch block to handle the exception in the elapsed event handler and
returning a value,
then the user won't event know exception occur in the handler.

[STAThread]

static void Main(string[] args)

{


System.Timers.Timer myTimer = new System.Timers.Timer(5000);


myTimer.Elapsed +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed);

myTimer.Start();

Console.ReadLine();

}

private static void myTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)

{

Console.WriteLine("Time elapsed");

throw new Exception("Exception from elapsed event handler");

}



static int _Main(string args[]) {
// just code along, and throw INFORMATIONAL errors
// if anything goes wrong.
if ( error )
throw new ParsingException(
string.Format("Invalid argument {0}", arg))
// ...
return 0;
}

static int Main(string args[]) {
#if !DEBUG
try {
#endif
return _Main(args);
#if !DEBUG
} catch ( Exception e ) {
Log(e);
throw;
#endif
}

The (#if !DEBUG) allows you to use the "break if not catched" setting in
the IDE usefully. You could use another symbol, DEBUG is just *so* handy
for me :)

This pattern is also pretty usefull when testing:

void Test() {
string[] valid_args = { "x" };
string[] invalid_args = { "y" };

AssertEquals(_Main(valid_args), 0);

ParseException threw = null;
try {
_Main(invalid_args);
} catch ( ParseException e ) {
threw = e;
}
AssertNull(ParseException);
}

--
Helge Jensen
mailto:[email protected]
sip:[email protected]
-=> Sebastian cover-music: http://ungdomshus.nu <=-
 
J

Jay B. Harlow [MVP - Outlook]

Doh!
| I would be curious on your take on the exceptions after you have had a
| chance to use them.
I would be curious on your take on the new exception events after you have
had a chance to use them.

Jay

| David,
|| I prefer a log twice option, the first time at the original site where
the
|| exception was caught, and once again at the top. The reason is to catch
| code
| Have you looked at the new .NET 2.0 AppDomain events pertaining to
| Exceptions?
|
| http://msdn2.microsoft.com/library/1dw188c1.aspx
|
| Such as CatchingException & ExceptionThrown. I have not tried it, reading
| about ExceptionThrown, it sounds like it may allow one to log the
exception
| at the original site, instead of splattering your code with a lot of Catch
| blocks...
|
| I would be curious on your take on the exceptions after you have had a
| chance to use them.
|
| Just a thought
| Jay
|
|
| ||
|| >
|| > What does wrapping it help the caller? Logging certainly didn't produce
|| > any additional information the caller would like to have.
|| >
|| > More importantly, you have robbed the caller of the possibility to
catch
|| > the exception by type, just use:
|| >
|| > catch ( Exception e ) {
|| > Log(e);
|| > throw;
|| > }
|| >
||
|| Except that in v1.1 using a naked throw causes the stack trace to get
| reset,
|| so you lose that information.
||
|| I prefer to catch-wrap-throw, as nothing is lost and you can add context
|| information. I use a helper method to
|| rethrow the original exception type, as in...
||
|| catch(Exception ex)
|| {
|| throw CloneException("Context info.",ex);
|| }
||
|| This preserves the original exception type, the stack trace info, and
adds
|| additional meaning.
||
|| >
|| > I really don't like that, it's just a very complicated way of doing
| goto,
|| > and there are better options: write one logging handler at the
| call-stack
|| > top, and then use exceptions to signal errors, knowing that someone
will
|| > catch, log, and whatever they feel is approrpriate.
||
|| I prefer a log twice option, the first time at the original site where
the
|| exception was caught, and once again at the top. The reason is to catch
| code
|| paths where an exception is inadvertently swallowed on its way up the
call
|| stack. This can be a problem in a large project with many different
|| components written by different developers - no one person has personal
|| knowledge of every piece of code in the system.
||
||
||
||
||
|
|
 
J

John Vottero

Kevin Yu said:
I don't know if it's a bug or not, in a timer_elapsed event handler, if an
exception occur,
it won't bubble back to the caller, since it's running in another thread,
so
if there is
no try catch block to handle the exception in the elapsed event handler
and
returning a value,
then the user won't event know exception occur in the handler.

You can use AppDomain.UnhandledException event to handle events from all
threads.
It's not quite the same as catching them since you can't continue.
 
H

Helge Jensen

Kevin said:
I don't know if it's a bug or not, in a timer_elapsed event handler, if an
exception occur,
it won't bubble back to the caller, since it's running in another thread, so
if there is
no try catch block to handle the exception in the elapsed event handler and
returning a value,
then the user won't event know exception occur in the handler.

That's the way (and the only viable) way that uncaught exceptions work.
The solution is that top-of-callstack methods *need* to consider what to
do when exceptions occur. This is equally relevant no matter how you use
exceptions.

Usually you don't write code directly into the thread-startable fuction,
but write it instead so that it can be invoked normally:

private static void f(ArgType1 arg1, ArgType2 arg2) { ... }

private static void myTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
try {
f((ArgType1)arg1, new ArgType2(...));
} catch ( Exception e ) {
Global.Log(e);
}
}

Further, you can add to the UnhandledException event in AppDomain to
spot where this rule is broken at runtime. And you can even Log from
there so you have a traceback for finding the culprit.

It would be nice with a thread-local UnhandledException, but it's really
not *that* often it would make sense, and you can implement your own
helper-class for it:

class LocalRun {
public public readonly Delegate F;
public public object[] args;
public event UnhandledExceptionEventHandler UnhandledException;
public LocalRun(Delegate F, object[] args) {
this.F = F;
this.args = args;
}
public void Run() {
try {
F.DynamicInvoke(args);
} catch ( Exception e ) {
try {
UnhandledException(e);
} catch ( Exception e ) {
// special defence against UnhandledException throwing required
// this is basically the only catch { /*ignore */ } that
// makes sense
}
throw;
}
}
}
 
K

Kevin Yu

John Vottero said:
You can use AppDomain.UnhandledException event to handle events from all
threads.
It's not quite the same as catching them since you can't continue.


no, looks like the AppDomain.UnhandledException event can't pick up the
exception either.
 
J

John Vottero

Kevin Yu said:
no, looks like the AppDomain.UnhandledException event can't pick up the
exception either.

The exception is passed to the event handler in the ExceptionObject property
of the UnhandledExceptionEventArgs argument.
 
D

David Levine

Helge Jensen said:
Yes, that's a bug. But the original trace is in the log, that's why you
did the catch, so it's not that bad.

It's only in the log if the catch routine logs it - mine does, but not
everyone does so.
That's not really wrapping, is it? That's working around the "throw;"-bug.
At least if you really are "cloning" ex.

Actually it really is wrapping. The routine CloneException uses reflection
to create an instance of the exception that was originally caught, passing
the original exception to the constructor as the InnerException. It looks
something like this...

static public System.Exception CloneException(string
message,System.Exception ex)
{
Type t = ex.GetType();
try
{
if ( t.IsSubclassOf(typeof(System.Exception)) )
{
Type[] types = new Type[2] { typeof(string),typeof(System.Exception) };
object[] args = new object[] {message,ex};
ConstructorInfo ci = t.GetConstructor(types);
if ( ci != null )
{
object o;
o = t.Assembly.CreateInstance(
t.FullName,false,BindingFlags.CreateInstance,null,args,null,null );
return (System.Exception)o;
}
}
}
catch(Exception uhOh)
{
SwallowException(uhOh,"Unable to CloneException of type {0}.",t ); //
trace it
}
// if here it was unable to create an instance of the same type. Create a
generic exception
// and return that.
return new System.Exception(message,ex);
} // CloneException


A nice workaround :)
thanks!


Only if the "Context info" doesn't shadow the information in ex, but is
made available on enquery.

It should be something meaningful otherwise the exception should not be
caught at all. Personally I find error messages that consist solely of "Null
Reference" to be as useless as the more generic "Something's f*&&kd", and a
lot less catchy. And yes, many years ago I inadvertently left that error
message in a shipping product...along with the product manager's home phone
number instead of support
It's a nice trick though, It (in effect) allows adding notes to an
exception in the form of objects not available at the error-site, but
non-theless important to understanding the error as the exception bubbles
the call-stack.

Exactly. It also avoids the use of custom exception types.
I recognize this problem, people writing:

try {
f();
} catch {};

should get a *very* serious talking-to.

Yes but it does happen, especially on a large team where many members are
experienced C/C++ but novice C# developers.

I also provided a routine called SwallowException that is supposed to put
into all catch handlers that do not otherwise log the exception. This has
allowed us to track down a large number of problems that were masked by evil
catch handlers like the one you showed here.
But how does the above help you with that?

It must be a very involved logfile-analysis to extract the relevant
information, especially since there is nothing that warns you this may be
the problem. The program explicitly *doesn't* terminate.

I usually don't want the program to terminate. In our applications most
exceptions do not signify a fatal condition, just one that the program logic
cannot usually automatically recover from... e.g. a "cable disconnected"
fault may be fatal in terms of the task, but not for the entire application.

I also use a fairly sophisticated diagnostic tracing layer that is much more
expressive then the exception logging mechanism.
How do you skip all the places where actual error-handling is done?

It's actually fairly simple although it does use an assumption which may be
incorrect. I use a routine like this...


static internal void PublishExceptionOnCreate(Exception ex)
{
if ( ex == null )
return; // sanity check failed
if ( !PublishOnCreate ) // global flag to disable this
return;
if ( ex.InnerException != null && ex.InnerException.InnerException !=
null )
return; // not first create call, so don't publish - **this is the
assumtion**
// this is used when an internal error occurs - don't try to publish it on
create
// because it might cause endless recursion.
if ( ex.GetType() == typeof(CustomPublisherException) )
return;
Publish(ex); // if here then publish
}


The key is the assumption that if the InnerException is ever not null then
it has already been published, because this implies that the exception has
already gone through a catch-wrap-throw phase and so has already been
published (the first time it was caught). I know that this will not always
be correct, but in practice it actually works rather well because so long
as all catch handlers use the same exception management layer (mine) it will
always use the same heuristics. And the worst that happens is that it gets
published a few too many times. In a properly designed system you should not
be getting flooded with exceptions, otherwise you've got bigger problems
then a few extra entries in a log file.
 
D

David Levine

Jay B. Harlow said:
David,
| I prefer a log twice option, the first time at the original site where
the
| exception was caught, and once again at the top. The reason is to catch
code
Have you looked at the new .NET 2.0 AppDomain events pertaining to
Exceptions?

I looked at them briefly when I played with Whidbey, but unfortunately the
project I am working on now is using the 1.1 framework so I haven't been
able to spend any time on it in months. However, my brief impression is that
a program that throws too many exceptions can really bog the system down
from the events getting fired. This might be a godsend because it might
force a lot of lazy developers to clean up their code :)


http://msdn2.microsoft.com/library/1dw188c1.aspx

Such as CatchingException & ExceptionThrown. I have not tried it, reading
about ExceptionThrown, it sounds like it may allow one to log the
exception
at the original site, instead of splattering your code with a lot of Catch
blocks...

I agree, I think it will be a really good thing but will also require a log
of discipline. On the whole I think it will encourage good practices,
because otherwise that event will get fired so much the noise will mask out
the really serious exceptions.
I would be curious on your take on the exceptions after you have had a
chance to use them.

Just a thought
Jay
I like them...I wish I was working on a Whidbey-based project. I also
really like generics, partial classes, the improved IDE, etc. MSFT is doing
a great job.
 
D

David Levine

Helge Jensen said:
That's the way (and the only viable) way that uncaught exceptions work.
The solution is that top-of-callstack methods *need* to consider what to
do when exceptions occur. This is equally relevant no matter how you use
exceptions.

The main problem I have with the UE handler in the v1.1 framework is that
the event is only delivered to subscribers running in the default appdomain.
If your handler is in another appdomain then it will never receive the
notification unless you write your own plumbing.
Usually you don't write code directly into the thread-startable fuction,
but write it instead so that it can be invoked normally:

private static void f(ArgType1 arg1, ArgType2 arg2) { ... }

private static void myTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
try {
f((ArgType1)arg1, new ArgType2(...));
} catch ( Exception e ) {
Global.Log(e);
}
}

I usually use a pattern similar to the async threading, where I catch and
save the exception on the worker thread and then rethrow it on the main
thread when it checks the results. Of course, this may not always be
possible but you can always save the exception object for later processing.
 
K

Kevin Yu

John Vottero said:
The exception is passed to the event handler in the ExceptionObject property
of the UnhandledExceptionEventArgs argument.

run this:

class Class1

{

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main(string[] args)

{


AppDomain.CurrentDomain.UnhandledException +=new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);


System.Timers.Timer myTimer = new System.Timers.Timer(5000);


myTimer.Elapsed +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed);

myTimer.Start();



Console.ReadLine();

}

private static void myTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)

{


Console.WriteLine("in timere elapsed handler, throwing exception...");

throw new Exception("Exception from elapsed event handler");

}

private static void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)

{

Console.WriteLine("Unhandled exception occured!");

}

}

CurrentDomain_UnhandledException never get called.
 
J

John Vottero

Kevin Yu said:
run this:

I can't explain that. It works as expected with a System.Threading.Timer.

class Class1

{

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main(string[] args)

{


AppDomain.CurrentDomain.UnhandledException +=new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);


System.Timers.Timer myTimer = new System.Timers.Timer(5000);


myTimer.Elapsed +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed);

myTimer.Start();



Console.ReadLine();

}

private static void myTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)

{


Console.WriteLine("in timere elapsed handler, throwing exception...");

throw new Exception("Exception from elapsed event handler");

}

private static void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)

{

Console.WriteLine("Unhandled exception occured!");

}

}

CurrentDomain_UnhandledException never get called.
 
H

Helge Jensen

That's because the C# code that runs "event" catches and discards the
exceptions. This bad behaviour is replicated in the threads that runs
events in System.Windows.Forms.

If the event-handler needs to "ignore" exceptions it should at least
notify someone. Best thing would be a place in the resource
(Timer/Control/Thread/...) where you can bind on an UnhandledException,
otherwise AppDomain.UnhandledException.
run this:
myTimer.Elapsed +=new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
private static void myTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e) {
throw new Exception("Exception from elapsed event handler"); }

CurrentDomain_UnhandledException never get called.

Because of the try {...} catch { /* ignore */ } policy taken by the code
that executes the ElapsedEvent.
 

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