How to terminate a thread in C#?
Thread.Abort
will "kill" the thread, but this is roughly equivalent to:
Scenario: You want to turn off your computer
Solution: You strap dynamite to your computer, light it, and run.
It's FAR better to trigger an "exit condition", either via CancellationTokenSource.Cancel
, setting some (safely accessed) "is running" bool, etc., and calling Thread.Join
. This is more like:
Scenario: You want to turn off your computer
Solution: You click start, shut down, and wait until the computer powers down.
Best way to terminate a thread
In general you have two options:
allow the thread to terminate itself. This covers your first option.
terminate the thread externally. This covers your other options.
And that's it. And none of them, in general, can prevent the threads from running for indefinite time after they should (from the programmer's intent point of view) terminate.
The most predictable approach is the first one. If terminating takes too long, try to do the processing in smaller steps to allow checking the termination flag more frequently. Also, note the IsBackground
flag which will help with the application being unable to close itself.
The whole problem with the other options is that any code (except for some special cases like finally
blocks) can be just interrupted in the middle of its execution, which can lead to some undesired results (e.g. some unmanaged resources not released) - as it is explained in Thread.Abort
documentation.
Note that the third approach in the newest versions of .NET framework is equivalent to calling the Abort
method on your executing threads, as explained in the documentation:
The threads in domain are terminated using the
Abort
method, which throws aThreadAbortException
in the thread. Although the thread should terminate promptly, it can continue executing for an unpredictable amount of time in a finally clause.
So it seems better to use Thread.Abort
from these two, as it's simpler and more readable.
If the first approach is problematic, and if you are well aware of the type of operations your thread is executing and there is no problem in interrupting them in-between then the "brutal" approach should be fine.
How to kill a thread instantly in C#?
The reason it's hard to just kill a thread is because the language designers want to avoid the following problem: your thread takes a lock, and then you kill it before it can release it. Now anyone who needs that lock will get stuck.
What you have to do is use some global variable to tell the thread to stop. You have to manually, in your thread code, check that global variable and return if you see it indicates you should stop.
c# Stop Thread with a button click
SampleFunction
is a method, not a Thread
object, so you can't call Abort()
like that.
You need to keep a reference to the Thread
:
var thread = new Thread(SampleFunction);
thread.Start();
Then you can call Abort()
when you want to kill it:
thread.Abort();
But keep in mind that it does kill it. The effect of Abort()
is that it throws a ThreadAbortException
in the thread. So it can stop at any moment and leave things in an unexpected state, so it may not be the best approach depending on what you're doing in the thread.
Here are a couple articles that discuss this and possibly better ways to stop a thread:
- Destroying threads
- Canceling threads cooperatively
Terminating a thread immediately and safely (C#)
This sort of thing can be implemented easier and cleaner using async/await rather than threads.
First we need to wrap the blocking console input method with one that is cancellable (and async). The method polls the console using KeyAvailable
and asynchronously delaying while checking the CancellationToken
.
public static async Task<ConsoleKeyInfo> ReadKeyAsync(CancellationToken cancellationToken)
{
while (!Console.KeyAvailable)
{
await Task.Delay(100, cancellationToken);
}
return Console.ReadKey();
}
Now we can start this async method and pass a cancellation token from a CancellationTokenSource
that will automatically cancel after a specific amount of time (10 seconds as an example).
public static async Task Main(string[] args)
{
Console.WriteLine("You have 10 seconds to press the Y key...");
var cts = new CancellationTokenSource(10_000);
try
{
while (true)
{
var key = await ReadKeyAsync(cts.Token);
if (key.Key == ConsoleKey.Y)
{
Console.WriteLine("Good job!");
break;
}
else
{
Console.WriteLine("Wrong Key");
}
}
}
catch (OperationCanceledException)
{
Console.Write("Time up!");
}
}
Stop / abort a class-loop thread, C#
Your code if(myBool == false) {theadDraw.Abort();}
isn't working because you're checking this once, immediately after the thread starts. And it isn't ever checked again (threadDate.Start()'
isn't a blocking call).
But, NET Framework contains the CancellationToken
concept which is used to cancel asynchronous code.
// Step 1, create a cancellation token:
CancellationTokenSource cancel = new CancellationTokenSource();
// Step 2, reference the token from inside your thread
void ThreadStartMethod() {
while (!cancel.IsCancellationRequested) {
// Do work ...
}
}
// Step 3, cancel the token when you need to
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
cancel.Cancel();
}
Note: make sure you re-create the cancellation token whenever you start the thread
How to kill a thread in C# effectively?
Set an Abort flag to tell the thread is needs to terminate. Append a dummy record to the ServiceBroker queue. The WAITFOR then returns. The thread then checks its 'Abort' flag and, finding it set, deletes the dummy record from the queue and exits.
Another variant would be to add a 'real' poison-pill record to the specification for the table monitored by the ServiceBroker - an illegal record-number, or the like. That would avoid touching the thread/s at all in any direct manner - always a good thing:) This might be more complex, especially if each work thread is expeceted to notify upon actual termination, but would still be effective if the work threads, ServiceBroker and DB were all on different boxes. I added this as an edit because, having thought a bit more about it, it seems more flexible, after all, if the threads normally only communicate via. the DB, why not shut them down with only the DB? No Abort(), no Interrupt() and, hopefully, no lockup-generating Join().
Terminating/joining a thread in C#
I decided to switch to using a timer. The code now looks like this, and the application works:
public partial class Form1 : Form
{
private System.Timers.Timer timer;
public Form1()
{
InitializeComponent();
timer = new System.Timers.Timer(60000);
}
private void Form1_Load(object sender, EventArgs e)
{
timeLabel.Text = TimeWriterSingleton.Instance.OutputTime();
timer.Elapsed += TimerElapsed;
timer.Enabled = true;
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
timeLabel.Text = TimeWriterSingleton.Instance.OutputTime();
}
}
How to terminate a thread from the UI using C#
First, the thread needs to be able to recognize that it should end. Change
void Thread_Clock() {
while(true) {
to
bool endRequested = false;
void Thread_Clock() {
while(!endRequested) {
And then set endRequested to True in your button click handler.
private void btnStop_Click(object sender, EventArgs e)
{
endRequested = true;
}
Note that for this specific case, it is probably more appropriate to use a Timer
http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx
Simply start and stop the timer as desired. You would update the clock from the timer's Tick() event.
Related Topics
Datagrid Column Width Doesn't Auto-Update
Sortable Jqgrid Using Linq to MySQL (Dblinq) and Dynamic Linq - Orderby Doesn't Work
Accessing a Property of Derived Class from the Base Class in C#
When Is Using the C# Ref Keyword Ever a Good Idea
No Itemchecked Event in a Checkedlistbox
Deserializing JSON Array into Strongly Typed .Net Object
Getting Relative Virtual Path from Physical Path
What Is the Correct Way to Cancel an Async Operation That Doesn't Accept a Cancellationtoken
Invalidprogramexception/Common Language Runtime Detected an Invalid Program
Efficient Way to Round Double Precision Numbers to a Lower Precision Given in Number of Bits
How to Get a List of Installed Updates and Hotfixes
Capture Screen on Server Desktop Session
Regular Expression to Get the Src of Images in C#
Get List<> Element Position in C# Using Linq