Is it possible to throw an exception into parent thread?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

How should I handle exception inside of a thread seperate from the UI thread?
Is this a way to throw them to the UI thread, or just using events that
describe an error occured?


Thanks,
Chris
 
Hi Chris,

Thanks for your post.

To handle the exception in the thead other than UI thread, I think we can
wrap the thead proc code in the try..catch clause. Like this:

Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();

void ThreadMethod() {
try
{
throw new InvalidOperationException();
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
}

Additionally, for the handled exceptions in the .Net application, there is
some rules we should be aware of how to handle it.(recover from the
unhandled exception.), I recommanded you read "How .NET Deals with
Unhandled Exceptions" section in the excellent article writen by Jason
Clark below:
"Unexpected Errors in Managed Applications"
http://msdn.microsoft.com/msdnmag/issues/04/06/NET/

Hope this helps

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
This is my code:

public void Install( Credentials credentials )
{
this.OnInstallStart( new InstallEventArgs(
StatusStart.Replace( "%N", this.name ) ) );
Thread installer = new Thread( this.InstallDriver );
InstallDriverArgs args = new InstallDriverArgs();

args.DriverName = this.name;
args.DriverInf = this.location;
args.Credentials = credentials;

installer.Start( args );
}

private void InstallDriver( object data )
{
InstallDriverArgs myArgs = ( InstallDriverArgs )data;

Impersonation impersonator = new Impersonation();
impersonator.Impersonate( myArgs.Credentials.Username, "",
myArgs.Credentials.Password );

ManagementPath win32Path = new ManagementPath(
"Win32_PrinterDriver" );


ManagementClass mc = new ManagementClass( win32Path );

mc.Properties["Name"].Value = myArgs.DriverName;
mc.Properties["InfName"].Value = myArgs.DriverInf;
object[] args = { mc };

try
{
mc.InvokeMethod( "AddPrinterDriver", args );
}
catch ( ManagementException ex )
{
PrinterDriverInstallException myEx =
new PrinterDriverInstallException( this, ex );

throw myEx;
}
finally
{
impersonator.UndoImpersonation();
}

//TODO Find out if successful

//http://msdn.microsoft.com/library/d...river_method_in_class_win32_printerdriver.asp
this.OnInstallEnd( new InstallEventArgs(
StatusEnd.Replace( "%N", this.name ) ) );
}

As you can see, I already have the try/catch block inside the working
thread, but I want to get it back to the UI thread to let them know an error
occured. Is it possible to get the exception back to the UI thread is the
question, or is it best to handle the exception inside the working thread and
raise an event to let the UI thread know there was an issue?

Thanks,
Chris

"Jeffrey Tan[MSFT]" said:
Hi Chris,

Thanks for your post.

To handle the exception in the thead other than UI thread, I think we can
wrap the thead proc code in the try..catch clause. Like this:

Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();

void ThreadMethod() {
try
{
throw new InvalidOperationException();
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
}

Additionally, for the handled exceptions in the .Net application, there is
some rules we should be aware of how to handle it.(recover from the
unhandled exception.), I recommanded you read "How .NET Deals with
Unhandled Exceptions" section in the excellent article writen by Jason
Clark below:
"Unexpected Errors in Managed Applications"
http://msdn.microsoft.com/msdnmag/issues/04/06/NET/

Hope this helps

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
balmerch said:
This is my code:
[snip code]

As you can see, I already have the try/catch block inside the working
thread, but I want to get it back to the UI thread to let them know an error
occured. Is it possible to get the exception back to the UI thread is the
question, or is it best to handle the exception inside the working thread and
raise an event to let the UI thread know there was an issue?
Hi Chris,

The real problem is that at the time that you're handling the
exception, you have no idea where the UI thread is - it may be sitting
idly waiting for a windows message, it may be deep down in the middle
of a loop, it could be anywhere.

The two ways I've handled this:

1) Handle the exception within the thread, set a flag somewhere, and
exit as gracefully as possible

2) Store the exception into a variable, exit gracefully. Then,
periodically the UI thread scans for exceptions from other threads and
deals with them as best it can.

in both cases for mine, I've had small classes which represent the
thread(s) (since I often have ten or twenty identical threads running),
and the flag/variable are part of this class. In this way, each thread
has it's own storage (and you can identify which thread had a problem,
identify more than one exception occurring, etc)

A 3rd way which *may* work, but involves a bit of mucking about is
marshalling the exception into an intptr and then sending a custom
windows message using P/Invoke, and overriding the message handling
loop of the UI thread. That saves the "polling" approach of the other
two, but it's a fair bit more complex.

Damien
 
Damien said:
A 3rd way which *may* work, but involves a bit of mucking about is
marshalling the exception into an intptr and then sending a custom
windows message using P/Invoke, and overriding the message handling
loop of the UI thread. That saves the "polling" approach of the other
two, but it's a fair bit more complex.

This is the approach I usually take. However, there is no need to
worry about custom windows messages. Just use Control.BeginInvoke to
send the exception to the UI thread. The worker thread will need a
reference a Form or Control for this to work. The following code
snippet only works on 2.0 since it uses anonymous methods. You can
easily adapt it to work on 1.1 or lower.

try
{
// Stuff that throws exceptions.
}
catch (Exception e)
{
ThreadStart method = delegate()
{
throw e;
};
yourForm.BeginInvoke(method);
}

Brian
 
Hi Chris,

Thanks for your feedback.

I think "Damien" and "Brian Gideon" has provided some comment about your
issue. Personally, I think Brian's Control.BeginInvoke way should be the
recommanded way of communicating to the UI thread in .Net winform.

Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Brian said:
This is the approach I usually take. However, there is no need to
worry about custom windows messages. Just use Control.BeginInvoke to
send the exception to the UI thread. The worker thread will need a
reference a Form or Control for this to work. The following code
snippet only works on 2.0 since it uses anonymous methods. You can
easily adapt it to work on 1.1 or lower.
Just goes to show - if there's a simple way to do something, I'll
always find a more difficult way to do it :-)

Mind you, my most recent use of this kind of mechanism is in ASP.NET,
where some long running tasks are kicked off in other threads, and then
the webpage refreshes every thirty seconds to update the status - so
I'm already having to do "polling" anyway, and there isn't a UI thread
:-)

Damien
 
Back
Top