ThreadAbortException occurs when the child thread is in catch block{}

F

foolmelon

If a childThread is in the middle of a catch block and handling an
exception caught, the main thread calls childThread.Abort(). At that
time a ThreadAbortException is thrown in the childThread. The question
is: after the ThreadAbortException is thrown, does the childThread
continue run the remaining code in the catch block?
 
D

Dustin Campbell

If a childThread is in the middle of a catch block and handling an
exception caught, the main thread calls childThread.Abort(). At that
time a ThreadAbortException is thrown in the childThread. The
question is: after the ThreadAbortException is thrown, does the
childThread continue run the remaining code in the catch block?

I don't think the code in the child thread's catch block will continue to
run. The documentation for Thread.Abort() mentions that, in .NET Framework
version 2.0, code in finally blocks will execute but it does not mention
catch blocks. You could test this be signalling the thread that aborts the
child thread from the child thread's catch block and then performing the
Abort and determining if the code after the signal is executed.

Best Regards,
Dustin Campbell
Developer Express Inc.
 
D

Dustin Campbell

It looks like the catch-block will be executed just like a finally block
will. Here's a sample console application that you can use to test this behavior:

using System;
using System.Threading;

namespace ThreadTest
{
class Program
{
static ManualResetEvent resetEvent = new ManualResetEvent(false);

static void ThreadProc()
{
string text = null;
try
{
Console.WriteLine(text.ToString());

Console.WriteLine("ThreadProc(): Code at end of try");
}
catch (NullReferenceException)
{
Console.WriteLine("ThreadState at start of catch-block: {0}", Thread.CurrentThread.ThreadState);
resetEvent.Set();
Thread.Sleep(1000);
Console.WriteLine("ThreadState at end of catch-block: {0}", Thread.CurrentThread.ThreadState);
}
finally
{
Console.WriteLine("ThreadProc(): finally-block executed");
}

Console.WriteLine("ThreadProc(): Code after finally-block");
}
static void Main(string[] args)
{
Thread t = new Thread(ThreadProc);
t.Start();
resetEvent.WaitOne();
t.Abort();
Console.WriteLine("Main(): Thread.Abort called");
}
}
}

This should be the output from this test app:

ThreadState at start of catch-block: Running
Main(): Thread.Abort called
ThreadState at end of catch-block: AbortRequested
ThreadProc(): finally-block executed

Note that the code at the end of the try block and after the finally block
is never executed. But, the code in the catch-blcok after the main thread
is signaled does execute even though the main thread calls Thread.Abort().
In fact, it demonstrates that the call to Abort has set the ThreadState to
AbortRequested.

Best Regards,
Dustin Campbell
Developer Express Inc.
 
F

foolmelon

Dustin said:
It looks like the catch-block will be executed just like a finally block
will. Here's a sample console application that you can use to test this behavior:

using System;
using System.Threading;

namespace ThreadTest
{
class Program
{
static ManualResetEvent resetEvent = new ManualResetEvent(false);

static void ThreadProc()
{
string text = null;
try
{
Console.WriteLine(text.ToString());

Console.WriteLine("ThreadProc(): Code at end of try");
}
catch (NullReferenceException)
{
Console.WriteLine("ThreadState at start of catch-block: {0}", Thread.CurrentThread.ThreadState);
resetEvent.Set();
Thread.Sleep(1000);
Console.WriteLine("ThreadState at end of catch-block: {0}", Thread.CurrentThread.ThreadState);
}
finally
{
Console.WriteLine("ThreadProc(): finally-block executed");
}

Console.WriteLine("ThreadProc(): Code after finally-block");
}
static void Main(string[] args)
{
Thread t = new Thread(ThreadProc);
t.Start();
resetEvent.WaitOne();
t.Abort();
Console.WriteLine("Main(): Thread.Abort called");
}
}
}

This should be the output from this test app:

ThreadState at start of catch-block: Running
Main(): Thread.Abort called
ThreadState at end of catch-block: AbortRequested
ThreadProc(): finally-block executed

Note that the code at the end of the try block and after the finally block
is never executed. But, the code in the catch-blcok after the main thread
is signaled does execute even though the main thread calls Thread.Abort().
In fact, it demonstrates that the call to Abort has set the ThreadState to
AbortRequested.

Best Regards,
Dustin Campbell
Developer Express Inc.

Hi Dustin,

I know the following are true according to the spec of .net:
1) if the ThreadAbortException happens in the try block, the remaining
of the try block should not run. But the finally block will run
regardless.
2) if the ThreadAbortException happens in the finally block, the
remaining of the finally block should run (in fact, .NET 1.1
implemented it incorrectly. It seems to be fixed in .NET 2.0)

The question is, if ThreadAbortException happens in the catch block,
should the remaining of the catch block run or not according to the
spec? Or in another word, does Microsoft implement the
ThreadAbortException handling correctly in .NET 2.0 when it occurs in
the catch block of the child thread?

Thanks,
Bill
 
D

Dustin Campbell

I know the following are true according to the spec of .net:
1) if the ThreadAbortException happens in the try block, the remaining
of the try block should not run. But the finally block will run
regardless.
2) if the ThreadAbortException happens in the finally block, the
remaining of the finally block should run (in fact, .NET 1.1
implemented it incorrectly. It seems to be fixed in .NET 2.0)
The question is, if ThreadAbortException happens in the catch block,
should the remaining of the catch block run or not according to the
spec? Or in another word, does Microsoft implement the
ThreadAbortException handling correctly in .NET 2.0 when it occurs in
the catch block of the child thread?

Bill, if you read my response carefully and run the test app, you'll find
that the remainder of the catch-block does run when a ThreadAbortException
occurs. If it didn't, this line would not have been sent to the console:
"ThreadState at end of catch-block: AbortRequested".

Best Regards,
Dustin Campbell
Developer Express Inc.
 
P

Peter Duniho

Dustin Campbell said:
Bill, if you read my response carefully and run the test app, you'll find
that the remainder of the catch-block does run when a ThreadAbortException
occurs. If it didn't, this line would not have been sent to the console:
"ThreadState at end of catch-block: AbortRequested".

That answers the question of what *does* happen. It doesn't answer the
question of what *should* happen.

I think Bill was asking the latter. I have to admit, I find it
non-intuitive that a ThreadAbortException doesn't get thrown immediately,
even when in the middle of a catch block. After all, as far as I know any
other exception that occurs while within the catch block gets thrown when it
happens.

It's definitely good to know what does happen. But it's also interesting to
know what should happen, especially when that's different from what does
happen. :)

Pete
 
W

Willy Denoyette [MVP]

V2 of the CLR no longer induces asynchronous Aborts (that is one thread
aborts another) while performing backout (catch, fault, filter or finaly
blocks). Note however that a host may always decide to escalate a CLR thread
Abort to a rude thread Abort, so be carefull when you rely on this, an
asynchronous thread abort should only be considered safe when being part of
a domain unload.


Willy.



|
| Dustin Campbell wrote:
| > It looks like the catch-block will be executed just like a finally block
| > will. Here's a sample console application that you can use to test this
behavior:
| >
| > using System;
| > using System.Threading;
| >
| > namespace ThreadTest
| > {
| > class Program
| > {
| > static ManualResetEvent resetEvent = new ManualResetEvent(false);
| >
| > static void ThreadProc()
| > {
| > string text = null;
| > try
| > {
| > Console.WriteLine(text.ToString());
| >
| > Console.WriteLine("ThreadProc(): Code at end of try");
| > }
| > catch (NullReferenceException)
| > {
| > Console.WriteLine("ThreadState at start of catch-block: {0}",
Thread.CurrentThread.ThreadState);
| > resetEvent.Set();
| > Thread.Sleep(1000);
| > Console.WriteLine("ThreadState at end of catch-block: {0}",
Thread.CurrentThread.ThreadState);
| > }
| > finally
| > {
| > Console.WriteLine("ThreadProc(): finally-block executed");
| > }
| >
| > Console.WriteLine("ThreadProc(): Code after finally-block");
| > }
| > static void Main(string[] args)
| > {
| > Thread t = new Thread(ThreadProc);
| > t.Start();
| > resetEvent.WaitOne();
| > t.Abort();
| > Console.WriteLine("Main(): Thread.Abort called");
| > }
| > }
| > }
| >
| > This should be the output from this test app:
| >
| > ThreadState at start of catch-block: Running
| > Main(): Thread.Abort called
| > ThreadState at end of catch-block: AbortRequested
| > ThreadProc(): finally-block executed
| >
| > Note that the code at the end of the try block and after the finally
block
| > is never executed. But, the code in the catch-blcok after the main
thread
| > is signaled does execute even though the main thread calls
Thread.Abort().
| > In fact, it demonstrates that the call to Abort has set the ThreadState
to
| > AbortRequested.
| >
| > Best Regards,
| > Dustin Campbell
| > Developer Express Inc.
|
| Hi Dustin,
|
| I know the following are true according to the spec of .net:
| 1) if the ThreadAbortException happens in the try block, the remaining
| of the try block should not run. But the finally block will run
| regardless.
| 2) if the ThreadAbortException happens in the finally block, the
| remaining of the finally block should run (in fact, .NET 1.1
| implemented it incorrectly. It seems to be fixed in .NET 2.0)
|
| The question is, if ThreadAbortException happens in the catch block,
| should the remaining of the catch block run or not according to the
| spec? Or in another word, does Microsoft implement the
| ThreadAbortException handling correctly in .NET 2.0 when it occurs in
| the catch block of the child thread?
|
| Thanks,
| Bill
|
 

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