Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stopping work from one thread using another thread

Not sure if my title is worded well, but whatever :)

I have two threads: the main thread with the work that needs to be done, and a worker thread that contains a form with a progress bar and a cancel button. In normal code, it would be the other way around, but I can't do that in this case.

When the user clicks the cancel button, a prompt is displayed asking if he wants to really cancel the work. The problem is that work continues on the main thread. I can get the main thread to stop work and such, but I would like for it to stop doing work when he clicks "Yes" on the prompt.

Example:

// Main thread work starts here    
    t1 = new Thread(new ThreadStart(progressForm_Start));
    t1.Start();

    // Working
    for (i = 0; i <= 10000; i++)
    {
        semaphore.WaitOne();
        if (pBar.Running)
            bgworker_ProgressChanged(i);
        semaphore.Release();
        if (pBar.IsCancelled) break; 
    }

    t1.Abort(); 
// Main thread work ends here

// Start progress bar form in another thread
void progressForm_Start()
{
    pBar.Status("Starting");
    pBar.ShowDialog();
}

I could theoretically include a prompt in the cancelWatch() function, but then I would have to do that everywhere I'm implementing this class.

like image 856
duraz0rz Avatar asked Aug 15 '26 16:08

duraz0rz


1 Answers

I have a couple of quick comments:

  1. Avoid using Thread.Abort() here's why.
  2. Make your thread a background thread: Thread.IsBackground = true (this will automatically exit the thread when your app exits).

Here is a detailed discussion on how to safely stop a thread from running: Is it safe to use a boolean flag to stop a thread from running in C#

To stop the work on the main thread you'd have to do something like this:

boolean volatile isRunning = true;

static void Main(...)
{
    // ...
    // Working
    for (i = 0; i <= 10000; i++)
    {
        semaphore.WaitOne();
        if (!isRunning) break; // exit if not running
        if (pBar.Running)
            bgworker_ProgressChanged(i);
        semaphore.Release();
    }
    //...
    t1.Interrupt();// make the worker thread catch the exception
}
// 
void cancelButton_Click(object sender, EventArgs e)
{
    isRunning = false; // optimistic stop
    semaphore.Release();
}
like image 55
Kiril Avatar answered Aug 17 '26 07:08

Kiril



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!