Thread.Abort - is it safe?

M

mehdi

Hi folks,
You know, the Thread class has got a method named Abort which
according to the msdn:

"Raises a ThreadAbortException in the thread on which it is invoked,
to begin the process of terminating the thread. Calling this method
usually terminates the thread."

I've had a long discussion with someone on not to use the mentioned
method unless under the most extreme cases. I believe that it's
equivalent to the TerminateThread Win32 API and everything that
applies to the mentioned Win32 API, is also in place when using the
Thread.Abort method. When the Abort method is executed, the target
thread has no chance to execute any user-mode code and its initial
stack is not deallocated. On the other hand, DLLs attached to the
thread are not notified that the thread is terminating. And therefore
the use of the mentioned method is completely at your own risk.

Correct me if I'm wrong.

Thank in advance.
Mehdi
 
N

Nicholas Paldino [.NET/C# MVP]

Medhi,

Calling Abort on a thread is different in .NET.

First, you have to understand that a thread is a logical construct in
..NET, not always guaranteed to be connected to a physical thread. While for
the most part when you run your apps, there is a distinct physical thread
that correlates to your Thread instance (which represents a logical thread),
there is no guarantee that will be the case. It's also dependent on the CLR
host. SQL Server, as a CLR host, for example, might run different logical
threads on the same thread, or even fibers.

Assuming that you are in a regular app though, Abort isn't going to call
TerminateThread. The CLR will wait for any interop call to complete on that
thread (if there is one currently taking place) and then a
ThreadAbortException will be thrown. Based on this, I'm assuming that the
exception will unwind the stack, and then the thread will simply stop
executing. TerminateThread doesn't need to be called because the thread has
stopped terminating at that point.
 
A

andrew

by the way mehdi,
Thread.Abort gives more headaches than what that win32 API function would.
In fact the win32 api is simpler because you actually know that its not good
to use it.

the Thread.Abort( ) is more complicated.
you need to remember that if its thrown when the code is an finalize block,
it does not run the rest of code from it.
also this exception is automatically rethrown at the end of a catch block.

i tried to mimic Thread.Abort in C++ code. i wrote an Abort(HANDLE hThread)
procedure which queues an APC to the thread. the APC proc is throwing an
exception.
 
M

mehdi

Medhi,

Calling Abort on a thread is different in .NET.

First, you have to understand that a thread is a logical construct in
.NET, not always guaranteed to be connected to a physical thread. While for
the most part when you run your apps, there is a distinct physical thread
that correlates to your Thread instance (which represents a logical thread),
there is no guarantee that will be the case. It's also dependent on the CLR
host. SQL Server, as a CLR host, for example, might run different logical
threads on the same thread, or even fibers.

Assuming that you are in a regular app though, Abort isn't going to call
TerminateThread. The CLR will wait for any interop call to complete on that
thread (if there is one currently taking place) and then a
ThreadAbortException will be thrown. Based on this, I'm assuming that the
exception will unwind the stack, and then the thread will simply stop
executing. TerminateThread doesn't need to be called because the thread has
stopped terminating at that point.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hi folks,
You know, the Thread class has got a method named Abort which
according to the msdn:
"Raises a ThreadAbortException in the thread on which it is invoked,
to begin the process of terminating the thread. Calling this method
usually terminates the thread."
I've had a long discussion with someone on not to use the mentioned
method unless under the most extreme cases. I believe that it's
equivalent to the TerminateThread Win32 API and everything that
applies to the mentioned Win32 API, is also in place when using the
Thread.Abort method. When the Abort method is executed, the target
thread has no chance to execute any user-mode code and its initial
stack is not deallocated. On the other hand, DLLs attached to the
thread are not notified that the thread is terminating. And therefore
the use of the mentioned method is completely at your own risk.
Correct me if I'm wrong.
Thank in advance.
Mehdi

Well, so you mean if I get a handle to a WDM driver, for instance, in
a newly created thread, and then aborting the thread execution using
the Abort method, the handle will be also released, automagically? and
the driver will be successfully unloaded? How are we supposed to know
the subtle nuances of how the Abort method works?

On the other hand, is there anyway to be notified whether a given
Win32 API is called? (maybe a Win32 API monitor or the like).

Thank you for your time,
Mehdi
 
N

Nicholas Paldino [.NET/C# MVP]

medhi,

As far as getting a handle to a WDM driver, if you are in the middle of
an interop call, then the call to Abort will wait for that. After the call,
the exception will be thrown. If you are properly disposing of the any
handles you have in a finally block (whether explicit or through the using
statement) then it should dispose of properly.

However, if you are in a finally block already and the code to release
any unmanaged handles has not excecuted yet, then Abort is called, then
those handles will not be released.

If you want to make sure that the DLL that you called through the
P/Invoke layer is released, I think you will have to call FreeLibrary, using
a module handle that you obtain through a call to GetModuleHandle. I don't
know how the P/Invoke layer will take this though, so you might want to be
careul in doing that.


All-in-all, calling Abort is just a bad idea, it creates too many "what
ifs". Instead of trying to use abort, why not have checks in the thread
code every so often to see if you should be exiting the thread?

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

mehdi said:
Medhi,

Calling Abort on a thread is different in .NET.

First, you have to understand that a thread is a logical construct in
.NET, not always guaranteed to be connected to a physical thread. While
for
the most part when you run your apps, there is a distinct physical thread
that correlates to your Thread instance (which represents a logical
thread),
there is no guarantee that will be the case. It's also dependent on the
CLR
host. SQL Server, as a CLR host, for example, might run different
logical
threads on the same thread, or even fibers.

Assuming that you are in a regular app though, Abort isn't going to
call
TerminateThread. The CLR will wait for any interop call to complete on
that
thread (if there is one currently taking place) and then a
ThreadAbortException will be thrown. Based on this, I'm assuming that
the
exception will unwind the stack, and then the thread will simply stop
executing. TerminateThread doesn't need to be called because the thread
has
stopped terminating at that point.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hi folks,
You know, the Thread class has got a method named Abort which
according to the msdn:
"Raises a ThreadAbortException in the thread on which it is invoked,
to begin the process of terminating the thread. Calling this method
usually terminates the thread."
I've had a long discussion with someone on not to use the mentioned
method unless under the most extreme cases. I believe that it's
equivalent to the TerminateThread Win32 API and everything that
applies to the mentioned Win32 API, is also in place when using the
Thread.Abort method. When the Abort method is executed, the target
thread has no chance to execute any user-mode code and its initial
stack is not deallocated. On the other hand, DLLs attached to the
thread are not notified that the thread is terminating. And therefore
the use of the mentioned method is completely at your own risk.
Correct me if I'm wrong.
Thank in advance.
Mehdi

Well, so you mean if I get a handle to a WDM driver, for instance, in
a newly created thread, and then aborting the thread execution using
the Abort method, the handle will be also released, automagically? and
the driver will be successfully unloaded? How are we supposed to know
the subtle nuances of how the Abort method works?

On the other hand, is there anyway to be notified whether a given
Win32 API is called? (maybe a Win32 API monitor or the like).

Thank you for your time,
Mehdi
 
M

mehdi

medhi,

As far as getting a handle to a WDM driver, if you are in the middle of
an interop call, then the call to Abort will wait for that. After the call,
the exception will be thrown. If you are properly disposing of the any
handles you have in a finally block (whether explicit or through the using
statement) then it should dispose of properly.

However, if you are in a finally block already and the code to release
any unmanaged handles has not excecuted yet, then Abort is called, then
those handles will not be released.

If you want to make sure that the DLL that you called through the
P/Invoke layer is released, I think you will have to call FreeLibrary, using
a module handle that you obtain through a call to GetModuleHandle. I don't
know how the P/Invoke layer will take this though, so you might want to be
careul in doing that.

All-in-all, calling Abort is just a bad idea, it creates too many "what
ifs". Instead of trying to use abort, why not have checks in the thread
code every so often to see if you should be exiting the thread?

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Medhi,
Calling Abort on a thread is different in .NET.
First, you have to understand that a thread is a logical construct in
.NET, not always guaranteed to be connected to a physical thread. While
for
the most part when you run your apps, there is a distinct physical thread
that correlates to your Thread instance (which represents a logical
thread),
there is no guarantee that will be the case. It's also dependent on the
CLR
host. SQL Server, as a CLR host, for example, might run different
logical
threads on the same thread, or even fibers.
Assuming that you are in a regular app though, Abort isn't going to
call
TerminateThread. The CLR will wait for any interop call to complete on
that
thread (if there is one currently taking place) and then a
ThreadAbortException will be thrown. Based on this, I'm assuming that
the
exception will unwind the stack, and then the thread will simply stop
executing. TerminateThread doesn't need to be called because the thread
has
stopped terminating at that point.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi folks,
You know, the Thread class has got a method named Abort which
according to the msdn:
"Raises a ThreadAbortException in the thread on which it is invoked,
to begin the process of terminating the thread. Calling this method
usually terminates the thread."
I've had a long discussion with someone on not to use the mentioned
method unless under the most extreme cases. I believe that it's
equivalent to the TerminateThread Win32 API and everything that
applies to the mentioned Win32 API, is also in place when using the
Thread.Abort method. When the Abort method is executed, the target
thread has no chance to execute any user-mode code and its initial
stack is not deallocated. On the other hand, DLLs attached to the
thread are not notified that the thread is terminating. And therefore
the use of the mentioned method is completely at your own risk.
Correct me if I'm wrong.
Thank in advance.
Mehdi
Well, so you mean if I get a handle to a WDM driver, for instance, in
a newly created thread, and then aborting the thread execution using
the Abort method, the handle will be also released, automagically? and
the driver will be successfully unloaded? How are we supposed to know
the subtle nuances of how the Abort method works?
On the other hand, is there anyway to be notified whether a given
Win32 API is called? (maybe a Win32 API monitor or the like).
Thank you for your time,
Mehdi

Thank you Nicholas,
I've never ever used the Abort method, even once. I was just trying to
get a straight answer to the above question, for someone else. Since,
I couldn't convince him that calling the Abort method is not a safe-
practice; exactly because of those "what ifs" you've already
mentioned.

Thank you again for your time,
Mehdi
 

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