How to kill Thread in my C# application? - c#

I want to kill/destroy the thread in my application on Button Click event.
private void stop_btn_Click(object sender, EventArgs e)
{
Thread.Sleep();
}
Does this event hang up my application?
That's the code where from my thread starts
DataTable myTable = new DataTable();`enter code here`
myTable = msgDataSet.Tables["text"];
DataRow[] myRow;
myRow = myTable.Select();
for (int x = 0; x < myRow.Count(); x++ )
{
SendKeys.SendWait(myRow[x]["msg"].ToString());
SendKeys.SendWait("{Enter}");
int sleep = int.Parse(textBox2.Text);
Thread.Sleep(sleep);
}
Thread Spam1 = new Thread(new ThreadStart(Send1));
Spam1.Start();

See this article for why you should never try to call Thread.Abort:
http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
The problem is that you break your exception safety within that thread. This is because Thread.Abort will throw an exception within that thread at some arbitrary point, which might be right after a resource is loaded, but before the thread enters a try/catch that would support clean unloading of that resource.
Instead you should build co-operative cancellation into the code you run in that thread. Then set some sort of "cancellation requested" state, and let the thread kill itself. E.g.:
foreach(var value in aBunchOfData)
{
if(isCancelled)
{
break;
}
// Continue processing here...
}
In this case you'd expose isCancelled, and have your parent thread set it to true.
This pattern is made clear if you use a BackgroundWorker to implement your background thread.

If you want to forcefully shut down a thread, you can call Abort() which will raise a ThreadAbortedException on the target thread
myThread.Abort()
The target thread has a chance to catch it and clean up any resources if needed (of course, it can also ignore it if it wants to by just catching the exception and moving on, but that is IMO bad practice)

The code you wrote will put UI thread to sleep->your application will hang. How do you implement threading? If you are using BackgroundWorker- you can enable thread cancellation, if you are using Task- you can provide cancel token to it. If you are using Thread- you can choose Abort() method.
PS..If you want to stop your application(main thread)-you can:
close main window || call application exit || call process kill....

Related

check if thread finished its method before "killing" it 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.

Thread.Join() causing deadlock

I have three threads in total. The first is the main UI thread, which starts a System.Threading.Thread (ExperimentThread), which in turn starts a BackgroundWorker (WorkerThread).
MainThread and WorkerThread both access a shared resource. I synchronise access to this resource with the following object:
private static readonly Object LockObject = new Object();
which I use as follows in the main loop of each thread:
lock (LockObject)
{
// Do something with shared resource here.
}
A cut-down version of ExperimentThread is as follows:
public void RunExperiment
{
while (!bStopThread)
{
lock (LockObject)
{
// Do something with shared resource here.
}
if (bStopThread)
{
break;
}
else
{
Application.DoEvents();
Thread.Sleep(250);
}
}
}
And for completeness here is the DoWork method of WorkerThread:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker Worker = sender as BackgroundWorker;
for (int X = 0; X < 200; X++)
{
if (Worker.CancellationPending)
{
e.Cancel = true;
return;
}
lock (LockObject)
{
// Do something with shared resource here.
}
}
}
This seems to work fine when both threads are running freely.
At some point the UI thread will terminate the ExperimentThread by setting one of its boolean fields to true and then wait for it to end, as follows:
if (ExperimentThread.IsAlive)
{
ExperimentThread.StopThread = true;
ExperimentThread.Join(); // this line seems to cause the deadlock?
}
As soon as Join() is called, a deadlock occurs on the shared resource being accessed by ExperimentThread and WorkerThread, and my application hangs indefinitely. This happens maybe 9 out of 10 times.
If I remove ExperimentThread.Join() from the code snippet above, the deadlock never occurs, and ExperimentThread appears to terminate gracefully (it then goes on to terminate WorkerThread by calling CancelAsync()).
Any ideas what could be the problem here?
(P.S. I've been using Console.WriteLine() to determine when locks are taken and released, which is what has lead me to believe there's a deadlock. Is there a better to determine this, I could be wrong?)
Is there a better to determine this, I could be wrong?
A better way to check this is to use something like the Concurrency Visualizer available in higher level SKUs of Visual Studio. It will allow you to see exactly what has locked each thread, and what handles threads are waiting on, etc.
As for the exact reason you are getting a deadlock - there isn't enough code to determine this, but common issues are:
ExperimentThread and the main thread (with the Join() call) are both locking on the same object - ie: within a lock(LockObject) statement.
ExperimentThread is using Control.Invoke to marshal a call back onto the UI thread. Since the UI thread is blocked (waiting on the Join()), it can never process messages, which will prevent ExperimentThread from completing.
That being said, in general, I would recommend using Task or Task<T> instead of a new Thread if you're using .NET 4 or higher. Task provides a much nicer API for working with threads, including allowing continuations instead of blocking. C# 5 extends this to even allow you to asynchronously wait for the task to complete.

Object Disposed exception and multi thread application

I have an application that start System.Threading.Timer, then this timer every 5 seconds read some information from a linked database and update GUI on main form of application;
Since the System.Threading.Timer create another thread for the Tick event, i need to use Object.Invoke for updating User Interface on the main Form of application with code like this :
this.Invoke((MethodInvoker)delegate()
{
label1.Text = "Example";
});
The app work very well, but sometimes when the user close the main form and then close the application, if the second thread on timer_tick event is updating the user interface on main thread the user get an ObjectDisposedException.
How can i do for stop and close the threading timer before closing the main form and avoiding then Object disposed exception ?
This is a bit of a tricky proposition as you must ensure the following on a given Close event
The timer is stopped. This is fairly straight forward
The control being updated isn't disposed when the delegate is run. Again straight forward.
The code currently running off of a timer tick has completed. This is harder but doable
There are no pending Invoke methods. This is quite a bit harder to accomplish
I've run into this problem before and I've found that preventing this problem is very problematic and involves a lot of messy, hard to maintain code. It's much easier to instead catch the exceptions that can arise from this situation. Typically I do so by wrapping the Invoke method as follows
static void Invoke(ISynchronizedInvoke invoke, MethodInvoker del) {
try {
invoke.Invoke(del,null);
} catch ( ObjectDisposedException ) {
// Ignore. Control is disposed cannot update the UI.
}
}
There is nothing inherently wrong with ignoring this exception if you're comfortable with the consequences. That is if your comfortable with the UI not updating after it's already been disposed. I certainly am :)
The above doesn't take care of issue #2 though and it still needs to be done manually in your delegate. When working with WinForms I often use the following overload to remove that manual check as well.
static void InvokeControlUpdate(Control control, MethodInvoker del) {
MethodInvoker wrapper = () => {
if ( !control.IsDisposed ) {
del();
}
};
try {
control.Invoke(wrapper,null);
} catch ( ObjectDisposedException ) {
// Ignore. Control is disposed cannot update the UI.
}
}
Note
As Hans noted ObjectDisposedException is not the only exception that can be raised from the Invoke method. There are several others, including at least InvalidOperationException that you need to consider handling.
System.Timers.Timer is a horrible class. There is no good way to stop it reliably, there is always a race and you can't avoid it. The problem is that its Elapsed event gets raised from a threadpool thread. You cannot predict when that thread actually starts running. When you call the Stop() method, that thread may well have already been added to the thread pool but didn't get around to running yet. It is subject to both the Windows thread scheduler and the threadpool scheduler.
You can't even reliably solve it by arbitrarily delaying the closing of the window. The threadpool scheduler can delay the running of a thread by up to 125 seconds in the most extreme cases. You'll reduce the likelihood of an exception by delaying the close by a couple of seconds, it won't be zero. Delaying the close for 2 minutes isn't realistic.
Just don't use it. Either use System.Threading.Timer and make it a one-shot timer that you restart in the event handler. Or use a System.Windows.Forms.Timer, it is synchronous.
A WF Timer should be your choice here because you use Control.Invoke(). The delegate target won't start running until your UI thread goes idle. The exact same behavior you'll get from a WF timer.
Create two booleans called 'StopTimer' and 'TimerStopped'. Set the timer's AutoReset property to false. Then format the Elapsed method to the following:
TimerStopped = false;
Invoke((MethodInvoker)delegate {
// Work to do here.
});
if (!StopTimer)
timer.Start();
else
TimerStopped = true;
This way you are preventing a race condition, checking if the timer should continue and reporting when the method has reached its end.
Now format your FormClosing event as follows:
if (!TimerStopped)
{
StopTimer = true;
Thread waiter = new Thread(new ThreadStart(delegate {
while (!TimerStopped) { }
Invoke((MethodInvoker)delegate { Close(); });
}));
waiter.Start();
e.Cancel = true;
}
else
timer.Dispose();
If the timer hasn't stopped yet, a thread is launched to wait until it has done so and then try to close the form again.

Starting multiple threads and keeping track of them from my .NET application

I would like to start x number of threads from my .NET application, and I would like to keep track of them as I will need to terminate them manually or when my application closes my application later on.
Example ==> Start Thread Alpha, Start Thread Beta .. then at any point in my application I should be able to say Terminate Thread Beta ..
What is the best way to keep track of opened threads in .NET and what do I need to know ( an id ? ) about a thread to terminate it ?
You could save yourself the donkey work and use this Smart Thread Pool. It provides a unit of work system which allows you to query each thread's status at any point, and terminate them.
If that is too much bother, then as mentioned anIDictionary<string,Thread> is probably the simplest solution. Or even simpler is give each of your thread a name, and use an IList<Thread>:
public class MyThreadPool
{
private IList<Thread> _threads;
private readonly int MAX_THREADS = 25;
public MyThreadPool()
{
_threads = new List<Thread>();
}
public void LaunchThreads()
{
for (int i = 0; i < MAX_THREADS;i++)
{
Thread thread = new Thread(ThreadEntry);
thread.IsBackground = true;
thread.Name = string.Format("MyThread{0}",i);
_threads.Add(thread);
thread.Start();
}
}
public void KillThread(int index)
{
string id = string.Format("MyThread{0}",index);
foreach (Thread thread in _threads)
{
if (thread.Name == id)
thread.Abort();
}
}
void ThreadEntry()
{
}
}
You can of course get a lot more involved and complicated with it. If killing your threads isn't time sensitive (for example if you don't need to kill a thread in 3 seconds in a UI) then a Thread.Join() is a better practice.
And if you haven't already read it, then Jon Skeet has this good discussion and solution for the "don't use abort" advice that is common on SO.
You can create a Dictionary of threads and assign them id's, like:
Dictionary<string, Thread> threads = new Dictionary<string, Thread>();
for(int i = 0 ;i < numOfThreads;i++)
{
Thread thread = new Thread(new ThreadStart(MethodToExe));
thread.Name = threadName; //Any name you want to assign
thread.Start(); //If you wish to start them straight away and call MethodToExe
threads.Add(id, thread);
}
If you don't want to save threads against an Id you can use a list and later on just enumerate it to kill threads.
And when you wish to terminate them, you can abort them. Better have some condition in your MethodToExe that allows that method to leave allowing the thread to terminate gracefully. Something like:
void MethodToExe()
{
while(_isRunning)
{
//you code here//
if(!_isRunning)
{
break;
}
//you code here//
}
}
To abort you can enumerate the dictionary and call Thread.Abort(). Be ready to catch ThreadAbortException
I asked a similar questions and received a bunch of good answers: Shutting down a multithreaded application
Note: my question did not require a graceful exit, but people still recommended that I gracefully exit from the loop of each thread.
The main thing to remember is that if you want to avoid having your threads prevent your process from terminating you should set all your threads to background:
Thread thread = new Thread(new ThreadStart(testObject.RunLoop));
thread.IsBackground = true;
thread.start();
The preferred way to start and manage threads is in a ThreadPool, but just about any container out there can be used to keep a reference to your threads. Your threads should always have a flag that will tell them to terminate and they should continually check it.
Furthermore, for better control you can supply your threads with a CountdownLatch: whenever a thread is exiting its loop it will signal on a CountdownLatch. Your main thread will call the CountdownLatch.Wait() method and it will block until all the threads have signaled... this allows you to properly cleanup and ensures that all your threads have shutdown before you start cleaning up.
public class CountdownLatch
{
private int m_remain;
private EventWaitHandle m_event;
public CountdownLatch(int count)
{
Reset(count);
}
public void Reset(int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException();
m_remain = count;
m_event = new ManualResetEvent(false);
if (m_remain == 0)
{
m_event.Set();
}
}
public void Signal()
{
// The last thread to signal also sets the event.
if (Interlocked.Decrement(ref m_remain) == 0)
m_event.Set();
}
public void Wait()
{
m_event.WaitOne();
}
}
It's also worthy to mention that the Thread.Abort() method does some strange things:
When a thread calls Abort on itself,
the effect is similar to throwing an
exception; the ThreadAbortException
happens immediately, and the result is
predictable. However, if one thread
calls Abort on another thread, the
abort interrupts whatever code is
running. There is also a chance that a
static constructor could be aborted.
In rare cases, this might prevent
instances of that class from being
created in that application domain. In
the .NET Framework versions 1.0 and
1.1, there is a chance the thread could abort while a finally block is
running, in which case the finally
block is aborted.
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. If the thread that calls Abort
holds a lock that the aborted thread
requires, a deadlock can occur.
After creating your thread, you can set it's Name property. Assuming you store it in some collection you can access it conveniently via LINQ in order to retrieve (and abort) it:
var myThread = (select thread from threads where thread.Name equals "myThread").FirstOrDefault();
if(myThread != null)
myThread.Abort();
Wow, there are so many answers..
You can simply use an array to hold the threads, this will only work if the access to the array will be sequantial, but if you'll have another thread accessing this array, you will need to synchronize access
You can use the thread pool, but the thread pool is very limited and can only hold fixed amount of threads.
As mentioned above, you can create you own thread pool, which in .NET v4 becomes much easier with the introduction of safe collections.
you can manage them by holding a list of mutex object which will determine when those threads should finish, the threads will query the mutex each time they run before doing anything else, and if its set, terminate, you can manage the mutes from anywhere, and since mutex are by defenition thread-safe, its fairly easy..
i can think of another 10 ways, but those seems to work. let me know if they dont fit your needs.
Depends on how sophisticated you need it to be. You could implement your own type of ThreadPool with helper methods etc. However, I think its as simple as just maintaining a list/array and adding/removing the threads to/from the collection accordingly.
You could also use a Dictionary collection and use your own type of particular key to retrieve them i.e. Guids/strings.
As you start each thread, put it's ManagedThreadId into a Dictionary as the key and the thread instance as the value. Use a callback from each thread to return its ManagedThreadId, which you can use to remove the thread from the Dictionary when it terminates. You can also walk the Dictionary to abort threads if needed. Make the threads background threads so that they terminate if your app terminates unexpectedly.
You can use a separate callback to signal threads to continue or halt, which reflects a flag set by your UI, for a graceful exit. You should also trap the ThreadAbortException in your threads so that you can do any cleanup if you have to abort threads instead.

Compact Framework 2.0: How can I stop a thread when an object is dispose?

I have this code:
Thread t = new Thread(() => UpdateImage(origin));
t.Name = "UpdateImageThread";
t.Start();
This code is created on a Custom Control. I want to stop this thread (if it's running) when the object is going to be dispose.
This custom control has the following method:
void IDisposable.Dispose()
{
/* My own code */
base.Dispose(true);
}
I think this is the place to put the code but:
How can I know is the thread is running?
How can I take a referece for the thread and stop it?
By the way, UpdateImage call a web service, so I think that it's waiting all of its life.
How can I finish this wait?
Thank you!
It depends a lot on what UpdateImage() does and how well it copes with the Image being disposed while it it still active. If UpdateImage() is your code and contains a loop you can tell it to stop (using a field like _stopping). If not, the best thing may be to do nothing - in the rare case of Disposing the control while the image is still updating you take the penalty of leaving it to the GC.
About how to get the Thread: By saving the reference when and where you create it, for instance int the private member _updateThread.
Now actually stopping (aborting) the thread is a (very) bad idea.
So you'll need an indicator, like
private bool _stopping = false;
And it is up to the UpdateImage() method to react to _stopping == true and stop with what it is doing.
Your Dispose() can then use
_stopping = true;
_updateThread.Join()
Save your thread variable 't' so that you can re-use it later.
Within your Dispose method you want something like:
void IDisposable.Dispose()
{
if(t.IsRunning)
{
cancelThreads = true; // Set some cancel signal that the thread should check to determine the end
t.Join(500); // wait for the thread to tidy itself up
t.Abort(); // abort the thread if its not finished
}
base.Dispose(true);
}
You should be careful aborting threads though, ensure that you place critical section of code within regions that won't allow the thread to stop before it has finished, and catch ThreadAbortExceptions to tidy anything up if it is aborted.
You can do something like this in the threads start method
public void DoWork()
{
try
{
while(!cancelThreads)
{
// Do general work
Thread.BeginCriticalRegion();
// Do Important Work
Thread.EndCriticalRegion();
}
}
catch(ThreadAbortException)
{
// Tidy any nastiness that occured killing thread early
}
}
I suggest to override the Dispose method in your Custom Control.
There you have the reference of your thread and you can call .Join() for example...

Categories