2

I've started a thread in c#, but I want to be able to abort it and don't really know how to.

private void createThread(){
     Thread threadDraw = new Thread(new ThreadStart(myMethod /*Starts a class which loops for a long time*/ ));
     threadDraw.Start();
     if(myBool == false) {theadDraw.Abort();}
}

myMethod is starting a class that runs on a loop. The thing is, I want to be able to stop the loop with a keypress (in my case space). Currently, I've tried with

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    /* Checks space press, if space press: make myBool = false */
}

It changes myBool into false and the method itself works.

The problem here is, createThread() doesn't constantly check if myBool is false, and thereby doesn't stop.

I've also tried

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    /*checks for spacepress, then {threadDraw.Abort()} */
}

but it doesn't work either, I have tried replacing private with public on createThread but still, doesn't work.

Additionally, I've been thinking about creating a KeyDown()-method inside of the class and have a break; in the loop but either I'm doing something wrong (likely) or it's not possible.

Filburt
  • 17,626
  • 12
  • 64
  • 115
FoxPaw
  • 186
  • 1
  • 9
  • Does this answer your question? [How to kill a thread instantly in C#?](https://stackoverflow.com/questions/1327102/how-to-kill-a-thread-instantly-in-c) – FoxPro May 02 '20 at 12:44

2 Answers2

1

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

James Woodall
  • 725
  • 7
  • 15
  • 1
    I recently tried with cancellation-token, but due to the loop being inside of the class it didn't work then. Although I've now moved the loop outside the class, and thereby I am now able to cancel it. Thanks! – FoxPaw May 03 '20 at 13:37
0

I have tried replacing private with public on createThread but still, doesn't work.

That will only change the visibility of the method, not the working of the method.

A thread executes the code only once. So likely your myMethod has a loop that prevents it from being terminated. The Abort way of terminating the threads is not graceful (See the Remarks section of the documentation). You already have a conditional variable in your code, myBool, you can use it inside the myMethod to gracefully exit the loop and let the thread terminate itself.

void myMethod() {
    while (myBool && myLogic) { // if myBool is false, short-circuit and leave
        // thread code here.
    }
}

This will help the thread know when to stop by getting out of the loop. Oh, and this approach requires your first Form1_KeyDown method where you set the myBool value.

Note that you do not need to use a while, you can use any other iterative structure like do...while or a for loop as well. The logic is to finish the loop as soon as myBool becomes false. Yes, a break will work too. :-)

Now, back to your statement:

I want to be able to abort it

If you want the threat to abort right away, then my approach will not work since it requires a conditional check before loop execution. So, you might expect a delay of few microseconds — if your business requires accuracy of microseconds then forcing a thread to shut down is needed with Abort.

Afzaal Ahmad Zeeshan
  • 15,669
  • 12
  • 55
  • 103