In MSDN, the description of the Thread.Abort() method says: "Calling this method usually terminates the thread."
Why not ALWAYS?
In which cases it doesn't terminate the thread?
Are there any other possibility to terminate threads?
Thread.Abort() injects a ThreadAbortException on the thread. The thread may cancel the request by calling Thread.ResetAbort(). Also, there are certain code parts, such as finally block that will execute before the exception is handled. If for some reason the thread is stuck in such a block the exception will never be raised on the thread.
As the caller has very little control over the state of the thread when calling Abort(), it is generally not advisable to do so. Pass a message to the thread requesting termination instead.
In which cases it doesn't terminate the thread?
This question is a duplicate.
What's wrong with using Thread.Abort()
Are there any other posibility to terminate threads?
Yes. Your problem is that you should never start up a thread that you cannot tell politely to stop, and it stops in a timely manner. If you are in a situation where you have to start up a thread that might be (1) hard to stop, (2) buggy, or worst of all (3) hostile to the user, then the right thing to do is to make a new process, start the thread in the new process, and then terminate the process when you want the thread to go down. The only thing that can guarantee safe termination of an uncooperative thread is the operating system taking down its entire process.
See my excessively long answer to this question for more details:
Using lock statement within a loop in C#
The relevant bit is the bit at the end where I discuss what the considerations are regarding how long you should wait for a thread to kill itself before you abort it.
Why not ALWAYS?
In which cases it doesn't termenate the thread?
For starters, a thread may catch a ThreadAbortException and cancel its own termination. Or it could perform a computation that takes forever while you're trying to abort it. Because of this, the runtime can't guarantee that the thread will always terminate after you ask it to.
ThreadAbortException has more:
When a call is made to the Abort method to destroy a thread, the common language runtime throws a ThreadAbortException. ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block. When this exception is raised, the runtime executes all the finally blocks before ending the thread. Since the thread can do an unbounded computation in the finally blocks, or call Thread.ResetAbort() to cancel the abort, there is no guarantee that the thread will ever end.
You don't need to Abort() a thread manually. The CLR will do all of the dirty work for you if you simply let the method in the thread return; that will end the thread normally.
FileStream.Read() to a named pipe that is currently not receiving anything (read call blocks while waiting for incoming data) will not respond to Thread.Abort(). It remains inside the Read() call.
What if a thread is holding a lock and is aborted / killed ? Resources remain stuck
It works fine when when a thread calls
abort itself but not by other thread.
Abort, forcefully terminates the
affected thread even if it has not
completed its task and provides no
opportunity for the cleanup of
resources
reference MSDN
see: Managed Threading Best Practices
I can't seem to abort a thread that is stuck in a loop:
//immortal
Thread th1 = new Thread(() => { while (true) {}});
I can however abort the thread if sleeps during the loop:
//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
ThreadAborts will not occur inside a finally block or between BeginCriticalRegion and EndCriticalRegion
Because you can catch the ThreadAbortException and call Thread.ResetAbort inside the handler.
OT: For a comprehensive, language-agnostic, questionably useful and darned funny take on concurrency, see Verity Stob!
As john feminella stated from MSDN
When this exception is raised, the runtime executes all the finally
blocks before ending the thread.
For example this Abort never ends:
var thread = new Thread(action) { IsBackground = true };
thread.Start();
Thread.Sleep(2000);
thread.Abort();
while (!thread.Join(1000))
{
Console.WriteLine(thread.ThreadState);
}
void action()
{
try
{
while (true) { }
}
catch { }
finally
{
while (true) { }
}
}
I've had cases where the thread has been too busy to hear the Abort() call, which usually results in a ThreadAbortingException being thrown to my code.
Related
I have 2 threads in my program. 1 is handling a GUI and the other is doing some word automation. Lets call them GUIThread and WorkerThread.
The WorkerThread is looping through methods using recursion.
The WorkerThread is only alive while doing the word automation and the user must be able to stop the word automation. Therefore I have implemented a "Stop" button on the GUI which simply kills/terminates the WorkerThread. However if I kill the WorkerThread while it's in the middle of a method it sometimes causes a problem in my word document (this is a longer story) and that's why I want to check if the WorkerThread has finished/returned from a method before I kill it.
This is what my code does when I hit the "Stop" button:
//Stops the worker thread = stops word automation in process
workerThread.Abort();
//This blocks the thread until the workerThread has aborted
while (workerThread.IsAlive) ;
My own suggestion/workaround for the problem was to have a global variable I could set each time the WorkerThread entered and left a method but this doesn't seem right to me. I mean I think there must be an easier way to deal with it.
However if I kill the WorkerThread while it's in the middle of a method it sometimes causes a problem in my word document
This is why you should never kill a thread. You can't say what the thread was doing, whether it is safe to kill? etc etc.
Abort isn't doing what you expect it to do. Look at the documentation, it is subtle Calling this method usually terminates the thread. Note the word usually and not always.
Yes, Abort will not kill the thread always. For example if the thread was running unmanaged code, CLR will not abort the thread, instead it will wait for the thread to return to managed code.
Sameway Abort will not do its job when thread is in Constrained Execution Region, finally blocks etc.
The CLR delays thread aborts for code that is executing in a CER.
For example: Try to run the following code and see what happens.
private void IWillNeverReturn()
{
Thread thread = new Thread(() =>
{
try
{
}
finally
{
while (true)
{ }
}
});
thread.Start();
Thread.Sleep(1000);
thread.Abort();
}
Let the thread decide when it should complete, Tell the thread that it should stop as soon as it can. You tell it using CancellationToken.
If you google for Thread.Abort Evil, you'll find lot of useful resources, Here is one.
I have been looking all over MSDN and can't find a reason why Thread can not be interrupted when sleeping within finally block. I have tried aborting with no success.
Is there any way how to wake up thread when sleeping within finally block?
Thread t = new Thread(ProcessSomething) {IsBackground = false};
t.Start();
Thread.Sleep(500);
t.Interrupt();
t.Join();
private static void ProcessSomething()
{
try { Console.WriteLine("processing"); }
finally
{
try
{
Thread.Sleep(Timeout.Infinite);
}
catch (ThreadInterruptedException ex)
{
Console.WriteLine(ex.Message);
}
}
}
Surprisingly MSDN claims thread CAN be aborted in finally block: http://msdn.microsoft.com/en-us/library/aa332364(v=vs.71).aspx
"There is a chance the thread could abort while a finally block is running, in which case the finally block is aborted."
edit
I find Hans Passant comment as best answer since this explains why Thread sometimes can and can not be interrupted/aborted in finally block. And that is when process is shutting down.
thanks
Aborting and interrupting threads should be avoided if possible as this can corrupt the state of a running program. For example, imagine you aborted a thread that was holding locks open to resources, these locks would never be released.
Instead consider using a signalling mechanism so that threads can co-operate with each other and so handle blocking and unblocking gracefully, e.g:
private readonly AutoResetEvent ProcessEvent = new AutoResetEvent(false);
private readonly AutoResetEvent WakeEvent = new AutoResetEvent(false);
public void Do()
{
Thread th1 = new Thread(ProcessSomething);
th1.IsBackground = false;
th1.Start();
ProcessEvent.WaitOne();
Console.WriteLine("Processing started...");
Thread th2 = new Thread(() => WakeEvent.Set());
th2.Start();
th1.Join();
Console.WriteLine("Joined");
}
private void ProcessSomething()
{
try
{
Console.WriteLine("Processing...");
ProcessEvent.Set();
}
finally
{
WakeEvent.WaitOne();
Console.WriteLine("Woken up...");
}
}
Update
Quite an interesting low-level issue. Although Abort() is documented, Interrupt() is much less so.
The short answer to your question is no, you cannot wake a thread in a finally block by calling Abort or Interrupt on it.
Not being able to abort or interrupt threads in finally blocks is by design, simply so that finally blocks have a chance to run as you would expect. If you could abort and interrupt threads in finally blocks this could have unintended consequences for cleanup routines, and so leave the application in a corrupted state - not good.
A slight nuance with thread interrupting, is that an interrupt may have been issued against the thread any time before it entered the finally block, but whilst it was not in a SleepWaitJoin state (i.e. not blocked). In this instance if there was a blocking call in the finally block it would immediately throw a ThreadInterruptedException and crash out of the finally block. Finally block protection prevents this.
As well as protection in finally blocks, this extends to try blocks and also CERs (Constrained Execution Region) which can be configured in user code to prevent a range of exceptions being thrown until after a region is executed - very useful for critical blocks of code which must be completed and delay aborts.
The exception (no pun intended) to this are what are called Rude Aborts. These are ThreadAbortExceptions raised by the CLR hosting environment itself. These can cause finally and catch blocks to be exited, but not CERs. For example, the CLR may raise Rude Aborts in response to threads which it has judged to be taking too long to do their work\exit e.g. when trying to unload an AppDomain or executing code within the SQL Server CLR. In your particular example, when your application shuts down and the AppDomain unloads, the CLR would issue a Rude Abort on the sleeping thread as there would be an AppDomain unload timeout.
Aborting and interrupting in finally blocks is not going to happen in user code, but there is slightly different behavior between the two cases.
Abort
When calling Abort on a thread in a finally block, the calling thread is blocked. This is documented:
The thread that calls Abort might block if the thread that is being aborted is in a protected region of code, such as a catch block, finally block, or constrained execution region.
In the abort case if the sleep was not infinite:
The calling thread will issue an Abort but block here until the finally block is exited i.e. it stops here and does not immediately proceed to the Join statement.
The callee thread has its state set to AbortRequested.
The callee continues sleeping.
When the callee wakes up, as it has a state of AbortRequested it will continue executing the finally block code and then "evaporate" i.e. exit.
When the aborted thread leaves the finally block: no exception is raised, no code after the finally block is executed, and the thread's state is Aborted.
The calling thread is unblocked, continues to the Join statement and immediately passes as the called thread has exited.
So given your example with an infinite sleep, the calling thread will block forever at step 1.
Interrupt
In the interrupt case if the sleep was not infinite:
Not so well documented...
The calling thread will issue an Interrupt and continue executing.
The calling thread will block on the Join statement.
The callee thread has its state set to raise an exception on the next blocking call, but crucially as it is in a finally block it is not unblocked i.e. woken.
The callee continues sleeping.
When the callee wakes up, it will continue executing the finally block.
When the interrupted thread leaves the finally block it will throw a ThreadInterruptedException on its next blocking call (see code example below).
The calling thread "joins" and continues as the called thread has exited, however, the unhandled ThreadInterruptedException in step 6 has now flattened the process...
So again given your example with an infinite sleep, the calling thread will block forever, but at step 2.
Summary
So although Abort and Interrupt have slightly different behavior, they will both result in the called thread sleeping forever, and the calling thread blocking forever (in your example).
Only a Rude Abort can force a blocked thread to exit a finally block, and these can only be raised by the CLR itself (you cannot even use reflection to diddle ThreadAbortException.ExceptionState as it makes an internal CLR call to get the AbortReason - no opportunity to be easily evil there...).
The CLR prevents user code from causing finally blocks to be prematurely exited for our own good - it helps to prevent corrupted state.
For an example of the slightly different behavior with Interrupt:
internal class ThreadInterruptFinally
{
public static void Do()
{
Thread t = new Thread(ProcessSomething) { IsBackground = false };
t.Start();
Thread.Sleep(500);
t.Interrupt();
t.Join();
}
private static void ProcessSomething()
{
try
{
Console.WriteLine("processing");
}
finally
{
Thread.Sleep(2 * 1000);
}
Console.WriteLine("Exited finally...");
Thread.Sleep(0); //<-- ThreadInterruptedException
}
}
The whole point of a finally block is to hold something that will not be affected by an interrupt or abort and will run to normal completion no matter what. Permitting a finally block to be aborted or interrupted would pretty much defeat the point. Sadly, as you noted, finally blocks can be aborted or interrupted due to various race conditions. This is why you will see many people advising you not to interrupt or abort threads.
Instead, use cooperative design. If a thread is supposed to be interrupted, instead of calling Sleep, use a timed wait. Instead of calling Interrupt signal the thing the thread waits for.
If I need to cancel some operation on a thread, when should I use Thread.Abort vs Thread.Interrupt. I read the documentation on it but not sure which scneario should i use a particular call between two.
If there is any third way of doing it, please let me knwo about it too with pro and cons.
I would avoid using Thread.Abort at all costs. Its behavior is much safer and predictable since .NET 2.0, but there are still some pretty serious pitfalls with it. Most of the aborts inside managed code can be made safe, but not all of them. For example, I believe there are some subtle problems if an abort request is triggered during the processing of a static constructor. Nevermind, the fact that the out-of-band exception can occur at anytime giving you little control over defining where the safe points for shutdown are located.
There are several acceptable ways to terminate a thread gracefully.
Use Thread.Interrupt
Poll a stopping flag
Use WaitHandle events
Specialized API calls
I discuss these methods in my answer here.
Most suggestions are already done, but here's an example how i would do it:
ManualResetEvent _requestTermination = new ManualResetEvent(false);
Thread _thread;
public void Init()
{
_thread = new Thread(() =>
{
while (!_requestTermination.WaitOne(0))
{
// do something usefull
}
}));
_thread.Start();
}
public void Dispose()
{
_requestTermination.Set();
// you could enter a maximum wait time in the Join(...)
_thread.Join();
}
This way the dispose will wait until the thread has exited.
If you need a delay within the thread, you shouldn't add Thread.Sleep.
Use the WaitOne(delayTime). This way you will never have to wait to terminate it.
I wouldn't use Thread.Abort ever. It causes an exception at an almost arbitrary time.
Be careful with Thread.Interrupt. If you don't build in some waiting or sleeping time the thread won't be interrupted.
Be careful with Thread.Abort. If you catch the ThreadAbortException your thread will terminate right after catch + finally.
(I like to use those methods to send a signal to my thread so that it knows it's terminating time, then clean up and exit.)
Is there a standard way to close out an application "cleanly" while some WaitHandle objects may be in the state of a current blocking call to WaitOne?
For example, there may be a background thread that is spinning along in a method like this:
while (_request.WaitOne())
{
try
{
_workItem.Invoke();
}
finally
{
OnWorkCompleted();
}
}
I see no obvious way to dispose of this thread without calling Thread.Abort (which from what I understand is discouraged). Calling Close on the _request object (an AutoResetEvent), however, will throw an exception.
Currently, the thread that is running this loop has its IsBackground property set to true, and so the application appears to close properly. However, since WaitHandle implements IDisposable, I'm unsure if this is considered kosher or if that object really ought to be disposed before the app exits.
Is this a bad design? If not, how is this scenario typically dealt with?
Define an additional WaitHandle called _terminate that will signal a request to terminate the loop and then use WaitHandle.WaitAny instead of WaitHandle.WaitOne.
var handles = { _request, _terminate };
while (WaitHandle.WaitAny(handles) == 0)
{
try
{
_workItem.Invoke();
}
finally
{
OnCompleteWork();
}
}
When a thread is blocking (regardless of what it's blocking on) you can call Thread.Interrupt() This will cause the exception ThreadInterruptedException (I believe, it might be a little different) You can handle this exception on the thread itself and do any neccesary clean up.
It's worth noting, that the thread will only throw the ThreadInterruptedException when it is blocking, if it's not blocking it won't be thrown until it next tries to block.
This is the "safe" way of ending threads from what I've read on the subject.
also worth noting: If the object implements both IDisposable and a finializer (which it will if it uses unmanaged resources) the GC will call the finalizer which normally calls dispose. Normally this is non-deterministic. However you can pretty much guarantee they will get called on application exit. Only under very special circumstances they wouldn't. (A .net environment termininating exception such as StackOverflowException is thrown)
Set the IsBackground property to true... it should automatically close the thread when your app ends.
Alternately, you can interrupt the thread by calling Thread.Interrupt and handle the ThreadInterruptedException. Another idea is to call _request.Set() and make the while loop check a volatile flag to determine if the application is closing or if it should continue:
private volatile bool _running = true;
while(_request.WaitOne() && _running)
{
//...
}
// somewhere else in the app
_running = false;
_request.Set();
I think the operating system will clean up after your process has finished. Because your thread is marked as IsBackground the CLR will end the process and all the threads within, so this is not a problem.
The application I am working on uses thread pool. Here's the basic pseudo code.
On the main thread
foreach(Object obj in Component.GetObject())
{
//Invoke the thread pool providing the call back (method to be called on the background// thread) and pass the object as the parameter.
}
//Wait for the threads to complete.
The "Component.GetObject" will basically return a CLR object using Yield return. This object needs to be processed by two other components on threads. So we are invoking the thread pool providing the call back method (that will invoke the two components).
If there is an exception on the spawned thread/s, the parent thread needs to be notified so that it can break out of the for loop (i.e. stop spawing more threads), wait for the spawned threads to complete and then handle the exception.
Based on my reading, one of the approaches would be have a "flag" variable on the main thread. If there is an exception on the spawned thread, the thread would set the variable using locking mechanism. The parent thread would check the "flag" variable before spawning new threads.
I would like to know if there is a better approach for handling this scenario. Thread pool is being used since it manages the queueing of threads if the "for" loop spawns more threads than the thread pool limit.
I think the standard way is to just throw the exception and let the code that handles the thread pool handle it. Is this not possible in your implementation?
Even if the exception is handled, nothing is stopping you from throwing one into your main thread from one of the other threads.
//thread code
try{
//something
}
catch (IOException e){
//handle your exception
//and then throw another one, that you can catch later
throw new ThreadFailedException()
}