473,396 Members | 1,996 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Exception Handling Question

I'm implementing a centralized exception handling routine using the
Enterprise Library Exception Management Application Block.

I trap all unhandled exceptions to one place using the following method:

// --- Create an Exception Handler for Thread Exceptions ----------------

Application.ThreadException += new
ThreadExceptionEventHandler(OnThreadException);

// --- Create an Exception Handler for Unhandled Exceptions -------------

AppDomain currentDomain = AppDomain.CurrentDomain;

currentDomain.UnhandledException += new
UnhandledExceptionEventHandler(OnUnhandledExceptio n);

private static void OnThreadException(object sender,

ThreadExceptionEventArgs t)

//
************************************************** ****************************

// Handles Normal Thread Exceptions

//
************************************************** ****************************

{

Exceptions.LogAndReportError(t.Exception);

}

private static void OnUnhandledException(object sender,

UnhandledExceptionEventArgs args)

//
************************************************** ****************************

// Handles All Unhandled Exceptions

//
************************************************** ****************************

{

Exceptions.LogAndReportError(args.ExceptionObject as System.Exception);

}

The problem I have is that exceptions that occur on a background thread are
not being picked up. If I do a "throw" on an exception in a background
thread it has no place to go and just disappears as an unhandled exception.
How can I pick up these exceptions without handling them in the background
thread?

Thanks,

Chuck Cobb
Apr 21 '06 #1
16 2509
On Fri, 21 Apr 2006 07:40:14 -0400, "Chuck Cobb"
<ch********@oxfordcorp.com> wrote:
The problem I have is that exceptions that occur on a background thread are
not being picked up. If I do a "throw" on an exception in a background
thread it has no place to go and just disappears as an unhandled exception.
How can I pick up these exceptions without handling them in the background
thread?


What .NET version is that? Joe Duffy's "Professional .NET Framework
2.0" states that Versions 1.0 and 1.1 used to silently swallow
unhandled exceptions on a background thread. Apparently there's
nothing you can do about that. Version 2.0 should correctly invoke
your UnhandledException handler.
--
http://www.kynosarges.de
Apr 21 '06 #2
On Fri, 21 Apr 2006 15:47:55 +0200, Christoph Nahr
<ch************@kynosarges.de> wrote:
What .NET version is that? Joe Duffy's "Professional .NET Framework
2.0" states that Versions 1.0 and 1.1 used to silently swallow
unhandled exceptions on a background thread. Apparently there's
nothing you can do about that. Version 2.0 should correctly invoke
your UnhandledException handler.


Just found confirmation on Jeff Atwood's weblog, right here:
http://www.codinghorror.com/blog/archives/000201.html

Scroll down to a reply by Jonathan Keljo, CLR Exceptions PM:

"Just to complicate things, in v1.0 and 1.1, an unhandled exception
did not always mean that your application would die. If the unhandled
exception occurred on anything other than the main thread or a thread
that began its life in unmanaged code, the CLR ate the exception and
allowed your app to keep going. This was generally evil, because what
would often happen was, for example, that ThreadPool threads would
silently die off, one by one, until your application wasn't actually
doing any work. Figuring out the cause of this kind of failure was
nearly impossible. [...]"

"In v2.0, an unhandled exception on any thread will take down the
application. We've found that it's tremendously easier to debug
crashes than it is to debug hangs or the silent-stoppage-of-work
problem described above."
--
http://www.kynosarges.de
Apr 21 '06 #3
Hi Christopher,

I am using .Net 2.0 and I can confirm that it is still swallowing exceptions
on a background thread. The code I used to test it looks like this

public static void BackgroundProcess
{
try
{
throw new Exception("Simulated Error");
}
catch
{
throw;
}
}

When I execute the above code, it creates the exception, goes to the catch
block and when it attempts to rethrow it using the "throw", it goes nowhere
"Christoph Nahr" <ch************@kynosarges.de> wrote in message
news:j1********************************@4ax.com...
On Fri, 21 Apr 2006 15:47:55 +0200, Christoph Nahr
<ch************@kynosarges.de> wrote:
What .NET version is that? Joe Duffy's "Professional .NET Framework
2.0" states that Versions 1.0 and 1.1 used to silently swallow
unhandled exceptions on a background thread. Apparently there's
nothing you can do about that. Version 2.0 should correctly invoke
your UnhandledException handler.


Just found confirmation on Jeff Atwood's weblog, right here:
http://www.codinghorror.com/blog/archives/000201.html

Scroll down to a reply by Jonathan Keljo, CLR Exceptions PM:

"Just to complicate things, in v1.0 and 1.1, an unhandled exception
did not always mean that your application would die. If the unhandled
exception occurred on anything other than the main thread or a thread
that began its life in unmanaged code, the CLR ate the exception and
allowed your app to keep going. This was generally evil, because what
would often happen was, for example, that ThreadPool threads would
silently die off, one by one, until your application wasn't actually
doing any work. Figuring out the cause of this kind of failure was
nearly impossible. [...]"

"In v2.0, an unhandled exception on any thread will take down the
application. We've found that it's tremendously easier to debug
crashes than it is to debug hangs or the silent-stoppage-of-work
problem described above."
--
http://www.kynosarges.de

Apr 21 '06 #4
On Fri, 21 Apr 2006 10:51:17 -0400, "Chuck Cobb"
<ch********@oxfordcorp.com> wrote:
When I execute the above code, it creates the exception, goes to the catch
block and when it attempts to rethrow it using the "throw", it goes nowhere


That's very strange. The UnhandledException handler doesn't get
triggered at all? Does it work if you just throw the exception,
outside of a try/catch block? Maybe the rethrow is the culprit.

In any case, that looks very much like a bug to me. Could you try
isolating a test case and post it here, or post a link to it?
--
http://www.kynosarges.de
Apr 21 '06 #5
ThreadException is meant to handle unhandled exceptions on the UI thread,
you need to install an UnhandledExceptionEventHandler to handle unhandled
excptions on auxiliary threads.

Willy.

"Chuck Cobb" <ch********@oxfordcorp.com> wrote in message
news:eT**************@TK2MSFTNGP04.phx.gbl...
| I'm implementing a centralized exception handling routine using the
| Enterprise Library Exception Management Application Block.
|
| I trap all unhandled exceptions to one place using the following method:
|
| // --- Create an Exception Handler for Thread Exceptions ----------------
|
| Application.ThreadException += new
| ThreadExceptionEventHandler(OnThreadException);
|
| // --- Create an Exception Handler for Unhandled Exceptions -------------
|
| AppDomain currentDomain = AppDomain.CurrentDomain;
|
| currentDomain.UnhandledException += new
| UnhandledExceptionEventHandler(OnUnhandledExceptio n);
|
|
|
| private static void OnThreadException(object sender,
|
| ThreadExceptionEventArgs t)
|
| //
|
************************************************** ****************************
|
| // Handles Normal Thread Exceptions
|
| //
|
************************************************** ****************************
|
| {
|
| Exceptions.LogAndReportError(t.Exception);
|
| }
|
|
|
| private static void OnUnhandledException(object sender,
|
| UnhandledExceptionEventArgs args)
|
| //
|
************************************************** ****************************
|
| // Handles All Unhandled Exceptions
|
| //
|
************************************************** ****************************
|
| {
|
| Exceptions.LogAndReportError(args.ExceptionObject as System.Exception);
|
| }
|
| The problem I have is that exceptions that occur on a background thread
are
| not being picked up. If I do a "throw" on an exception in a background
| thread it has no place to go and just disappears as an unhandled
exception.
| How can I pick up these exceptions without handling them in the background
| thread?
|
| Thanks,
|
| Chuck Cobb
|
|
Apr 21 '06 #6
I have an UhandledExceptionEventHandler installed in the main thread, but it
doesn't seem to be picking up exceptions that originate in another thread.
I've tried installing it in the other thread and it still doesn't seem to be
picking up the exception.

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:ep**************@TK2MSFTNGP04.phx.gbl...
ThreadException is meant to handle unhandled exceptions on the UI thread,
you need to install an UnhandledExceptionEventHandler to handle unhandled
excptions on auxiliary threads.

Willy.

"Chuck Cobb" <ch********@oxfordcorp.com> wrote in message
news:eT**************@TK2MSFTNGP04.phx.gbl...
| I'm implementing a centralized exception handling routine using the
| Enterprise Library Exception Management Application Block.
|
| I trap all unhandled exceptions to one place using the following method:
|
| // --- Create an Exception Handler for Thread
Exceptions ----------------
|
| Application.ThreadException += new
| ThreadExceptionEventHandler(OnThreadException);
|
| // --- Create an Exception Handler for Unhandled
Exceptions -------------
|
| AppDomain currentDomain = AppDomain.CurrentDomain;
|
| currentDomain.UnhandledException += new
| UnhandledExceptionEventHandler(OnUnhandledExceptio n);
|
|
|
| private static void OnThreadException(object sender,
|
| ThreadExceptionEventArgs t)
|
| //
|
************************************************** ****************************
|
| // Handles Normal Thread Exceptions
|
| //
|
************************************************** ****************************
|
| {
|
| Exceptions.LogAndReportError(t.Exception);
|
| }
|
|
|
| private static void OnUnhandledException(object sender,
|
| UnhandledExceptionEventArgs args)
|
| //
|
************************************************** ****************************
|
| // Handles All Unhandled Exceptions
|
| //
|
************************************************** ****************************
|
| {
|
| Exceptions.LogAndReportError(args.ExceptionObject as System.Exception);
|
| }
|
| The problem I have is that exceptions that occur on a background thread
are
| not being picked up. If I do a "throw" on an exception in a background
| thread it has no place to go and just disappears as an unhandled
exception.
| How can I pick up these exceptions without handling them in the
background
| thread?
|
| Thanks,
|
| Chuck Cobb
|
|

Apr 21 '06 #7
Don't know what could be wrong with your code, but herewith a complete
sample that may set you on the right track.

using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace Whatever
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void throwUI_Click(object sender, EventArgs e)
{
throw new Exception("Thrown from UI thread");
}
private void throwNonUI_Click(object sender, EventArgs e)
{
new Thread(delegate()
{
throw new Exception("Thrown from Aux thread");
}).Start();
}
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.throwUI = new Button();
this.throwNonUI = new Button();
this.SuspendLayout();

this.throwUI.Location = new System.Drawing.Point(12, 12);
this.throwUI.Name = "throwUI";
this.throwUI.Size = new System.Drawing.Size(95, 23);
this.throwUI.TabIndex = 0;
this.throwUI.Text = "Throw on UI";
this.throwUI.Click += new System.EventHandler(this.throwUI_Click);

this.throwNonUI.Location = new System.Drawing.Point(12, 42);
this.throwNonUI.Name = "throwUI";
this.throwNonUI.Size = new System.Drawing.Size(95, 23);
this.throwNonUI.TabIndex = 0;
this.throwNonUI.Text = "Throw on non UI";
this.throwNonUI.Click += new
System.EventHandler(this.throwNonUI_Click);

this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(283, 150);

this.Controls.Add(this.throwUI);
this.Controls.Add(this.throwNonUI);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
private Button throwUI;
private Button throwNonUI;
}
public class Program
{
[STAThread]
static void Main()
{
Application.ThreadException += delegate(object sender,
ThreadExceptionEventArgs e)
{
string errorMsg = String.Format("{0}", e.Exception.Message);
MessageBox.Show(errorMsg, "Unhandled exception",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
};
// Ignore configuration file settings - always route to
application handler.
Application.SetUnhandledExceptionMode(UnhandledExc eptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += delegate(object
sender, UnhandledExceptionEventArgs e)
{
string errorMsg = String.Format("{0} - IsTerminating = {1}",
e.ExceptionObject.ToString(), e.IsTerminating);
MessageBox.Show(errorMsg, "Unhandled exception",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
};
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}
Willy.

"Chuck Cobb" <ch********@oxfordcorp.com> wrote in message
news:uO**************@TK2MSFTNGP03.phx.gbl...
|I have an UhandledExceptionEventHandler installed in the main thread, but
it
| doesn't seem to be picking up exceptions that originate in another thread.
| I've tried installing it in the other thread and it still doesn't seem to
be
| picking up the exception.
|
| "Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
| news:ep**************@TK2MSFTNGP04.phx.gbl...
| > ThreadException is meant to handle unhandled exceptions on the UI
thread,
| > you need to install an UnhandledExceptionEventHandler to handle
unhandled
| > excptions on auxiliary threads.
| >
| > Willy.
| >
| > "Chuck Cobb" <ch********@oxfordcorp.com> wrote in message
| > news:eT**************@TK2MSFTNGP04.phx.gbl...
| > | I'm implementing a centralized exception handling routine using the
| > | Enterprise Library Exception Management Application Block.
| > |
| > | I trap all unhandled exceptions to one place using the following
method:
| > |
| > | // --- Create an Exception Handler for Thread
| > Exceptions ----------------
| > |
| > | Application.ThreadException += new
| > | ThreadExceptionEventHandler(OnThreadException);
| > |
| > | // --- Create an Exception Handler for Unhandled
| > Exceptions -------------
| > |
| > | AppDomain currentDomain = AppDomain.CurrentDomain;
| > |
| > | currentDomain.UnhandledException += new
| > | UnhandledExceptionEventHandler(OnUnhandledExceptio n);
| > |
| > |
| > |
| > | private static void OnThreadException(object sender,
| > |
| > | ThreadExceptionEventArgs t)
| > |
| > | //
| > |
| >
************************************************** ****************************
| > |
| > | // Handles Normal Thread Exceptions
| > |
| > | //
| > |
| >
************************************************** ****************************
| > |
| > | {
| > |
| > | Exceptions.LogAndReportError(t.Exception);
| > |
| > | }
| > |
| > |
| > |
| > | private static void OnUnhandledException(object sender,
| > |
| > | UnhandledExceptionEventArgs args)
| > |
| > | //
| > |
| >
************************************************** ****************************
| > |
| > | // Handles All Unhandled Exceptions
| > |
| > | //
| > |
| >
************************************************** ****************************
| > |
| > | {
| > |
| > | Exceptions.LogAndReportError(args.ExceptionObject as
System.Exception);
| > |
| > | }
| > |
| > | The problem I have is that exceptions that occur on a background
thread
| > are
| > | not being picked up. If I do a "throw" on an exception in a
background
| > | thread it has no place to go and just disappears as an unhandled
| > exception.
| > | How can I pick up these exceptions without handling them in the
| > background
| > | thread?
| > |
| > | Thanks,
| > |
| > | Chuck Cobb
| > |
| > |
| >
| >
|
|
Apr 21 '06 #8
Thanks for posting this code I tried it out and the primary difference
between your code and my code is how it starts an auxiliary thread:

Your code:
new Thread(delegate()

{

ThrowExceptionInsideTryCatch();

}).Start();

My Code:

MethodInvoker mi = new MethodInvoker(ThrowExceptionOutsideTryCatch);

mi.BeginInvoke(null, null);

If I start an auxiliary thread using your method, it correctly catches the
exception from the auxiliary thread. If I start it my way, it doesn't work.
I have no idea why it should be different.

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:uD**************@TK2MSFTNGP05.phx.gbl...
Don't know what could be wrong with your code, but herewith a complete
sample that may set you on the right track.

using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace Whatever
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void throwUI_Click(object sender, EventArgs e)
{
throw new Exception("Thrown from UI thread");
}
private void throwNonUI_Click(object sender, EventArgs e)
{
new Thread(delegate()
{
throw new Exception("Thrown from Aux thread");
}).Start();
}
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.throwUI = new Button();
this.throwNonUI = new Button();
this.SuspendLayout();

this.throwUI.Location = new System.Drawing.Point(12, 12);
this.throwUI.Name = "throwUI";
this.throwUI.Size = new System.Drawing.Size(95, 23);
this.throwUI.TabIndex = 0;
this.throwUI.Text = "Throw on UI";
this.throwUI.Click += new
System.EventHandler(this.throwUI_Click);

this.throwNonUI.Location = new System.Drawing.Point(12, 42);
this.throwNonUI.Name = "throwUI";
this.throwNonUI.Size = new System.Drawing.Size(95, 23);
this.throwNonUI.TabIndex = 0;
this.throwNonUI.Text = "Throw on non UI";
this.throwNonUI.Click += new
System.EventHandler(this.throwNonUI_Click);

this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(283, 150);

this.Controls.Add(this.throwUI);
this.Controls.Add(this.throwNonUI);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
private Button throwUI;
private Button throwNonUI;
}
public class Program
{
[STAThread]
static void Main()
{
Application.ThreadException += delegate(object sender,
ThreadExceptionEventArgs e)
{
string errorMsg = String.Format("{0}", e.Exception.Message);
MessageBox.Show(errorMsg, "Unhandled exception",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
};
// Ignore configuration file settings - always route to
application handler.

Application.SetUnhandledExceptionMode(UnhandledExc eptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += delegate(object
sender, UnhandledExceptionEventArgs e)
{
string errorMsg = String.Format("{0} - IsTerminating = {1}",
e.ExceptionObject.ToString(), e.IsTerminating);
MessageBox.Show(errorMsg, "Unhandled exception",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
};
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}
Willy.

"Chuck Cobb" <ch********@oxfordcorp.com> wrote in message
news:uO**************@TK2MSFTNGP03.phx.gbl...
|I have an UhandledExceptionEventHandler installed in the main thread, but
it
| doesn't seem to be picking up exceptions that originate in another
thread.
| I've tried installing it in the other thread and it still doesn't seem
to
be
| picking up the exception.
|
| "Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
| news:ep**************@TK2MSFTNGP04.phx.gbl...
| > ThreadException is meant to handle unhandled exceptions on the UI
thread,
| > you need to install an UnhandledExceptionEventHandler to handle
unhandled
| > excptions on auxiliary threads.
| >
| > Willy.
| >
| > "Chuck Cobb" <ch********@oxfordcorp.com> wrote in message
| > news:eT**************@TK2MSFTNGP04.phx.gbl...
| > | I'm implementing a centralized exception handling routine using the
| > | Enterprise Library Exception Management Application Block.
| > |
| > | I trap all unhandled exceptions to one place using the following
method:
| > |
| > | // --- Create an Exception Handler for Thread
| > Exceptions ----------------
| > |
| > | Application.ThreadException += new
| > | ThreadExceptionEventHandler(OnThreadException);
| > |
| > | // --- Create an Exception Handler for Unhandled
| > Exceptions -------------
| > |
| > | AppDomain currentDomain = AppDomain.CurrentDomain;
| > |
| > | currentDomain.UnhandledException += new
| > | UnhandledExceptionEventHandler(OnUnhandledExceptio n);
| > |
| > |
| > |
| > | private static void OnThreadException(object sender,
| > |
| > | ThreadExceptionEventArgs t)
| > |
| > | //
| > |
| >
************************************************** ****************************
| > |
| > | // Handles Normal Thread Exceptions
| > |
| > | //
| > |
| >
************************************************** ****************************
| > |
| > | {
| > |
| > | Exceptions.LogAndReportError(t.Exception);
| > |
| > | }
| > |
| > |
| > |
| > | private static void OnUnhandledException(object sender,
| > |
| > | UnhandledExceptionEventArgs args)
| > |
| > | //
| > |
| >
************************************************** ****************************
| > |
| > | // Handles All Unhandled Exceptions
| > |
| > | //
| > |
| >
************************************************** ****************************
| > |
| > | {
| > |
| > | Exceptions.LogAndReportError(args.ExceptionObject as
System.Exception);
| > |
| > | }
| > |
| > | The problem I have is that exceptions that occur on a background
thread
| > are
| > | not being picked up. If I do a "throw" on an exception in a
background
| > | thread it has no place to go and just disappears as an unhandled
| > exception.
| > | How can I pick up these exceptions without handling them in the
| > background
| > | thread?
| > |
| > | Thanks,
| > |
| > | Chuck Cobb
| > |
| > |
| >
| >
|
|

Apr 21 '06 #9

"Chuck Cobb" <ch********@oxfordcorp.com> wrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
| Thanks for posting this code I tried it out and the primary difference
| between your code and my code is how it starts an auxiliary thread:
|
| Your code:
| new Thread(delegate()
|
| {
|
| ThrowExceptionInsideTryCatch();
|
| }).Start();
|
| My Code:
|
| MethodInvoker mi = new
MethodInvoker(ThrowExceptionOutsideTryCatch);
|
| mi.BeginInvoke(null, null);
|

This doesn't start a auxiliary thread, it delegates the
ThrowExceptionOutsideTryCatch function to execute on the 'UI thread', but as
you call this from the UI thread, it simply boils down into a simple call to
ThrowExceptionOutsideTryCatch.

Willy.

Apr 21 '06 #10
Thanks...
"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:OP**************@TK2MSFTNGP04.phx.gbl...

"Chuck Cobb" <ch********@oxfordcorp.com> wrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
| Thanks for posting this code I tried it out and the primary difference
| between your code and my code is how it starts an auxiliary thread:
|
| Your code:
| new Thread(delegate()
|
| {
|
| ThrowExceptionInsideTryCatch();
|
| }).Start();
|
| My Code:
|
| MethodInvoker mi = new
MethodInvoker(ThrowExceptionOutsideTryCatch);
|
| mi.BeginInvoke(null, null);
|

This doesn't start a auxiliary thread, it delegates the
ThrowExceptionOutsideTryCatch function to execute on the 'UI thread', but
as
you call this from the UI thread, it simply boils down into a simple call
to
ThrowExceptionOutsideTryCatch.

Willy.

Apr 22 '06 #11
Thanks. First, I could indeed reproduce the problem.

But as Willy already said, just calling some variant of Invoke usually
doesn't start a background thread at all -- it merely performs an
invocation on the current thread, same as just writing out the method
call. That's true even for BeginInvoke/EndInvoke (on the Control
class) which only perform cross-thread marshalling if needed.

Nevertheless, the UnhandledException handler should be triggered. But
this is apparently one of the undocumented features of the
undocumented MethodInvoker.BeginInvoke method that you were using. How
do you know it's undocumented and should not be used? Because this
method does not appear in the MSDN docs, and its IntelliSense display
does not show any description other than the prototype.

In fact, MethodInvoker offers only a single "official" invocation
method, and that's DynamicInvoke (inherited from its base class
Delegate). And when I used that documented method the
UnhandledException handler was properly triggered -- for either
ThrowException... method, whichever is executed first.

Moral: Don't use undocumented .NET Framework methods! Actually, don't
use MethodInvoker at all. It's just a simple delegate, and the three
methods it offers in addition to Delegate/MulticastDelegate are all
intended for internal Windows.Forms use only. The class should never
have been publically exposed in the first place IMO.
--
http://www.kynosarges.de
Apr 22 '06 #12
Christoph,

See inline..

Willy.

"Christoph Nahr" <ch************@kynosarges.de> wrote in message
news:1u********************************@4ax.com...
| Thanks. First, I could indeed reproduce the problem.
|
| But as Willy already said, just calling some variant of Invoke usually
| doesn't start a background thread at all -- it merely performs an
| invocation on the current thread, same as just writing out the method
| call. That's true even for BeginInvoke/EndInvoke (on the Control
| class) which only perform cross-thread marshalling if needed.
|
| Nevertheless, the UnhandledException handler should be triggered.

No it should not, the exception is thrown on the UI thead, so the
ThreadException handler is invoked.
UnhandledException handlers are only invoked when "unhandled" exceptions are
originating from non UI threads.
But
| this is apparently one of the undocumented features of the
| undocumented MethodInvoker.BeginInvoke method that you were using. How
| do you know it's undocumented and should not be used? Because this
| method does not appear in the MSDN docs, and its IntelliSense display
| does not show any description other than the prototype.
|
| In fact, MethodInvoker offers only a single "official" invocation
| method, and that's DynamicInvoke (inherited from its base class
| Delegate). And when I used that documented method the
| UnhandledException handler was properly triggered -- for either
| ThrowException... method, whichever is executed first.
|
| Moral: Don't use undocumented .NET Framework methods! Actually, don't
| use MethodInvoker at all. It's just a simple delegate, and the three
| methods it offers in addition to Delegate/MulticastDelegate are all
| intended for internal Windows.Forms use only. The class should never
| have been publically exposed in the first place IMO.
| --
| http://www.kynosarges.de
Apr 22 '06 #13
On Sat, 22 Apr 2006 11:23:45 +0200, "Willy Denoyette [MVP]"
<wi*************@telenet.be> wrote:
No it should not, the exception is thrown on the UI thead, so the
ThreadException handler is invoked.
UnhandledException handlers are only invoked when "unhandled" exceptions are
originating from non UI threads.


Willy, haven't you read the rest of my post? The UnhandledException
handler *was* triggered when BeginInvoke was changed to DynamicInvoke,
or when the exception methods were called directly. The
ThreadException handler *was not* triggered.

As to why, I'm not sure. In the test program the exception is thrown
before a form is even constructed, so technically there is no GUI
(Windows Forms) thread at the time of the exception. Remember that
ThreadException is a Windows Forms feature, not a general threading
feature. Possibly it requires a window event queue to work.
--
http://www.kynosarges.de
Apr 22 '06 #14
Oh dear, oh dear. Attention: I'm a dumbass. Willy is also a dumbass.
Chuck is very smart and was actually mostly right. Should have read
the chapter on asynchronous operations in Jeff Richter's "CLR via C#"
before replying. I'm very sorry... here comes the correct version.

I got completely sidetracked by reminiscences of Control.BeginInvoke
which does not start a new thread. But in fact, the MethodInvoker
methods Invoke/BeginInvoke/EndInvoke are undocumented because they're
*auto-generated* for each delegate class. The BeginInvoke method is
proper to call and does, in fact, start a new background thread.

I no longer understand why the MSDN docs say that MethodInvoker.Invoke
is "for internal use" only; that does not seem to make sense. All of
these methods should be proper for anyone's use.

Okay. So why didn't UnhandledException get called? That's because
the auto-generated BeginInvoke method of a delegate executes on a
thread in the CLR thread pool, and any exceptions thrown by a thread
pool thread are automatically swallowed by the CLR until the
corresponding EndInvoke is called, at which point they're thrown.

So Chuck should see his UnhandledException handler activated when the
BeginInvoke call is paired with an EndInvoke call.

All this is explained in Jeff Richter's "CLR via C#", chapter 23,
pages 614f. Ironically, it's the book I tell everyone to read... that
was the last chapter I had not gotten around to read until now.
--
http://www.kynosarges.de
Apr 22 '06 #15
On Sat, 22 Apr 2006 14:10:20 +0200, Christoph Nahr
<ch************@kynosarges.de> wrote:
I no longer understand why the MSDN docs say that MethodInvoker.Invoke
is "for internal use" only; that does not seem to make sense. All of
these methods should be proper for anyone's use.


Jesus, what's wrong with me? The MSDN docs don't say that at all,
that was some other method I was looking up. Scratch that paragraph.
--
http://www.kynosarges.de
Apr 22 '06 #16
Well, actually I didn't pay attention to the BeginIvoke call (I even didn't
look at the attached code), I only noticed the MethodInvoker, which was
enough to conclude that the exception was not thrown on an "auxiliary"
thread (but being a dumbass, I wrongly assumed that it was on the UI
thread). Notice that I call an "auxiliary thread", a thread that is
explicitly created via a call to a Thread class constructor. Only unhandled
exceptions originating from "auxiliary" threads are routed to the
UnhandledException handler, 'unhandled' exceptions originating from pool
threads are not, they have to be handled explicitly, as you correctly
mentioned. Note that every BeginInvoke on a delegate has to be paired with
an EndInvoke call, this is mandatory on the CLR, failing to do this may
result in handle leaks.

Willy.

"Christoph Nahr" <ch************@kynosarges.de> wrote in message
news:hr********************************@4ax.com...
| Oh dear, oh dear. Attention: I'm a dumbass. Willy is also a dumbass.
| Chuck is very smart and was actually mostly right. Should have read
| the chapter on asynchronous operations in Jeff Richter's "CLR via C#"
| before replying. I'm very sorry... here comes the correct version.
|
| I got completely sidetracked by reminiscences of Control.BeginInvoke
| which does not start a new thread. But in fact, the MethodInvoker
| methods Invoke/BeginInvoke/EndInvoke are undocumented because they're
| *auto-generated* for each delegate class. The BeginInvoke method is
| proper to call and does, in fact, start a new background thread.
|
| I no longer understand why the MSDN docs say that MethodInvoker.Invoke
| is "for internal use" only; that does not seem to make sense. All of
| these methods should be proper for anyone's use.
|
| Okay. So why didn't UnhandledException get called? That's because
| the auto-generated BeginInvoke method of a delegate executes on a
| thread in the CLR thread pool, and any exceptions thrown by a thread
| pool thread are automatically swallowed by the CLR until the
| corresponding EndInvoke is called, at which point they're thrown.
|
| So Chuck should see his UnhandledException handler activated when the
| BeginInvoke call is paired with an EndInvoke call.
|
| All this is explained in Jeff Richter's "CLR via C#", chapter 23,
| pages 614f. Ironically, it's the book I tell everyone to read... that
| was the last chapter I had not gotten around to read until now.
| --
| http://www.kynosarges.de
Apr 23 '06 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: adi | last post by:
Dear all, This is more like a theoretical or conceptual question: which is better, using exception or return code for a .NET component? I had created a COM object (using VB6), which uses...
44
by: craig | last post by:
I am wondering if there are some best practices for determining a strategy for using try/catch blocks within an application. My current thoughts are: 1. The code the initiates any high-level...
3
by: dhussong | last post by:
I'm trying to implement a generic exception handling routine that will write information to a text file at the time the exception occurred. I am using the Microsoft Application Block for Exception...
3
by: Larry Herbinaux | last post by:
I have built an asychronous TCP Server that uses the thread pool. I have two levels of exception handling in case the handling of the inner catch block throws an exception. The outer catch block...
5
by: Bry | last post by:
I've created a class that offers an enhanced way of handling fatal exceptions. The class allows the user to optionaly submit a http based anonymous error report to myself, and also records details...
14
by: jehugaleahsa | last post by:
Hello: As an avid reader of C++ books, I know a lot of programmers out there are confronted with the challenge of exception safety. For those who don't know what it is, it is writing code in...
2
by: jayapal | last post by:
Hi , I am using the NEW operator to allocate the memory in many places of my code.But I am not doing any error hadling or exception handling.Can any one suggests me how to do exception handling,...
1
by: George2 | last post by:
Hello everyone, Such code segment is used to check whether function call or exception- handling mechanism runs out of memory first (written by Bjarne), void perverted() { try{
35
by: eliben | last post by:
Python provides a quite good and feature-complete exception handling mechanism for its programmers. This is good. But exceptions, like any complex construct, are difficult to use correctly,...
9
by: =?Utf-8?B?UmFq?= | last post by:
How do I know which methods will throw exception when I am using FCL or other third party .Net library? I am developer of mostly native Windows applications and now .Net. After working few...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.