check if thread finished its method before "killing" it c# - c#

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.

Related

killing a long running thread that is blocking on another child process to end

So, a little background. I have a program that creates a child process that runs long term and does some processing that we don't really care about for this question. It exists, and it needs to keep existing. So after starting that child process I start a thread that watches that child process and blocks waiting for it to end by Process.WaitForExit() and if it ends, it will restart the child process and then wait again. Now the problem is, how do I gracefully shut all of this down? If I kill the child process first, the thread waiting on it will spin it up again, so I know that the watcher thread needs to be killed first. I have been doing this by Thread.Abort() and then just catching the ThreadAbortException and returning ending the watcher thread and then I kill my child process. But I have been told that Thread.Abort() should be avoided at all costs and is possibly no longer supported in .Net core? So my question is why is Thread.Abort() so dangerous if I am catching the ThreadAbortException? and what is the best practice for immediately killing that thread so it doesn't have a chance to spin up the child thread again during shut down?
What you are looking for is way to communicate across threads. There are multiple ways to do this but they all have specific conditions applicable.
For example mutex and semaphore are available across processes. events or wait handles are specific to a given process, etc. Once you know the details of these you can use them to send signal from one thread to another.
A simple setup for your requirement can be -
Create a resetevent before spawning any of your threads.
Let the child thread begin. In your parent wait on the reset event that you have created.
Let the child thread reset the event.
In your parent thread the wait state is completed, you can take further actions, such as kicking of the thread again and waiting on it or simply cleaning up and walking out of execution.
Thread.Abort is an unclean way of finishing your processing. If you read the msdn article here - https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.abort?view=net-6.0 the remark clearly tells you that you cant be sure what current state your thread execution was in. Your thread may not get opportunity to follow up with important clean up tasks, such as releasing resources that it does not require no more.
This can also lead to deadlock if you have more complicated constructs in place, such as thread being aborted doing so from protected region of code, such as a catch block or a finally block. If the thread that calls Abort holds a lock that the aborted thread is waiting on, a deadlock can acquire.
Key to remember in multithreading is that it is your responsibility to let the logic have a clean way of reaching to completion and finish thread's execution.
Please note that steps suggested above is one way of doing it. Depending on your requirements it can be restructured/imporved further. For example, if you are spawning another process, you will require kernel level objects such as mutex or semaphore. Objects like event or flag cant work across the process.
Read here - https://learn.microsoft.com/en-us/dotnet/standard/threading/overview-of-synchronization-primitives for more information.
As mentioned by others, Thread.Abort has major issues, and should be avoided if at all possible. It can raise the exception at any point in the code, in a possibly completely unexpected location, and possibly leave data in a highly corrupted state.
In this instance, it's entirely unnecessary.
You should change the waiting thread to use async instead. For example, you can do something like this.
static async Task RunProcessWithRestart()
{
using cancel = new CancellationTokenSource();
try
{
while (true)
{
using (var process = CreateMyProcessAndStart())
{
await process.WaitForExitAsync(cancel.Token);
}
}
}
catch(OperationCanceledException)
{
}
}
static CancellationTokenSource cancel;
public static void StartWaitForProcess()
{
Task.Run(RunProcessWithRestart);
}
public static void ShutdownWaitForProcess()
{
cancel.Cancel();
}
An alternative, which doesn't require calling Cancel() from a separate shutdown function, is to subscribe to the AppDomain.ProcessExit event.
static async Task RunProcessWithRestart()
{
using var cancel = new CancellationTokenSource();
AppDomain.ProcessExit += (s, e) => cancel.Cancel();
try
{
while (true)
{
using (var process = CreateMyProcessAndStart())
{
await process.WaitForExitAsync(cancel.Token);
}
}
}
catch(OperationCanceledException)
{
}
}
public static void StartWaitForProcess()
{
Task.Run(RunProcessWithRestart);
}

Wait for a thread to actually start in c#

I need to start a thread, but continue just after the thread is actually running. Now my code looks like:
splashthread.IsBackground = false;
splashthread.Start();
Thread.Sleep(100); // Wait for the thread to start
I'm not fond of these voodoo sleeps (to say the least), so I'm looking for more nifty way of doing the above.
Any ideas?
Something like this:
var splashStart = new ManualResetEvent(false);
var splashthread = new Thread(
() =>
{
splashStart.Set();
// Your thread code here...
});
splashthread.Start();
splashStart.WaitOne();
Don't forget to Dipose splashStart or if it's appropriate in your code use a using block.
Edit: Didn't confirm the original code in the IDE. Changed Wait to WaitOne() as per comment below.
Why do you care when the other thread starts? You well may be interested in knowing when the new thread has reached some particular milestone, and you could use any number of synchronization primitives to deal with that (in addition to events, if the new thread is going to be initializing something visible to the constructing thread, you could use a monitor lock with Monitor.Wait/Monitor.Pulse. Monitor locks are lightweight, but require a little care.
In particular, the thread which is going to wait for the other thread must check within a synclock whether the object has been initialized, before it does Monitor.Wait. Otherwise it's possible that the new thread might perform its Monitor.Pulse before the main thread has reached its Monitor.Wait. Adding the object-initialized check would prevent that scenario. If the new thread hasn't initialized the object before the launcher thread entered the synclock to check and wait, it won't be able to perform the Pulse until after the launcher thread gives up its lock via Monitor.Wait. If the new thread has initialized the object before the launcher thread entered the synclock, the launcher thread will see that and not wait at all.

Thread.Abort vs Thread.Interrupt

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.)

How can I ensure a determenistic result for this multithreading problem?

Consider the following test snippet:
// act
AutoResetEvent workDoneEvent = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(delegate
{
ProcessAndSignal(processor, workDoneEvent);
}, null);
// let worker thread have a go
workDoneEvent.WaitOne();
blockingFetcher.WaitForNextMessage = false;
// assert
Assert.That(processor.StopCause, Is.Null);
}
private static void ProcessAndSignal(MessageProcessor processor, AutoResetEvent workDoneEvent)
{
workDoneEvent.Set();
// this invocation will block until the WaitForNextMessageFlag is set
processor.ProcessMessages();
}
Ideal scenario:
ProcessAndSignalMethod is queued on the thread pool but does not start to execute.
The main thread blocks (autoResetEvent.WaitOne())
A worker thread starts to execute the "ProcessAndSignal" method
The worker threads has enough time to signal the flag and start execution of the ProcessMessages method
The main thread is spawned back into life and sets the property which will cause the ProcessAndSignal method to complete gracefully
Can the following scenario occur?
1) ProcessAndSignal() will start to execute before the main thread sets the AutoResetEvent to WaitOne() which will cause a deadlock (the processor.ProcessMessages() will go into an infinitive loop)
Yes, the scenario can occur. Yes it can deadlock if you don't declare the bool variable as volatile. Just don't use a bool, use an event like you did.
The logic looks weird, it smells like you are trying to let the main thread wait for the processing to be completed. The workDoneEvent doesn't actually signal that the work was done. Right now the main thread will check the assert before the worker is done, that can't be good. If the intention was that it signals that the worker is done then ProcessAndSignal should be the one calling Set(), at the end of the method. And the main thread should call WaitOne().
If this is at all accurate then you just should not use QUWI, just call ProcessAndSignal directly without using a thread. Far more efficient, zero odds for threading problems.

C# Thread Termination and Thread.Abort()

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.

Categories