In my windows forms application, I start a thread to do some work.
I need to be able to pause what that thread is doing without having to restart the whole thread or start a new thread.

I have some code but somehow it does not look thread safe. It appears to work, but I'm sure that does not mean that it will not run into a race problem.

I have reproduced some minimalistic code to show what I'm doing, and I'm hoping someone might advise me a better way to accomplish my goal, which is basically that two methods called from separate threads might try to read the some bool field (paused) at the same time.

Thanks for reading.

namespace CSThreadingTest
{
    public delegate void ThreadDelegate();

    public partial class Form1 : Form
    {
        private bool paused = false;
        private int counter = 0;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.start.Enabled = false;
            Thread t = new Thread(new ThreadStart(MyThread));
            t.IsBackground = true;
            t.Start();
        }

        //Thread method started with start button
        private void MyThread()
        {
            while (true)
            {
                if (!paused)
                {
                    Invoke(new ThreadDelegate(Count));
                }
                Thread.Sleep(500);
            }

        }

        // Method that thread invokes
        private void Count()
        {
            myTextbox.Text = counter.ToString();
            counter++;
        }

        //Pause button
        private void button2_Click(object sender, EventArgs e)
        {
            paused = !paused;
        }
    }
}

Recommended Answers

All 6 Replies

Maybe this would be sufficient. I know it's depreciated but I cannot see any harm in it myself.

t.Suspend();
paused = !paused;
t.Resume();

Have you looked into Tasks yet?

I had not, nor was I aware of them.
Thanks, Tasks look very interesting and may be just what I need.

I swear there was a way to request a pause, I just can't for the life of me remember it.

However, may I offer one suggestion. Place a lock around that pause variable.

Such as

//Thread method started with start button
private void MyThread()
{
    while (true)
    {
        lock(MyLock)
        {
            if (!paused)
            {
                Invoke(new ThreadDelegate(Count));
            }
        }
        Thread.Sleep(500);
    }
}

//Pause button
private void button2_Click(object sender, EventArgs e)
{
    lock(MyLock)
    {
        paused = !paused;
    }
}

You'll need to make sure of course to declare that "MyLock" variable. But that's quite simple Object MyLock = new Object(); (I think there were parenthsis at the end of an object)

If I remember right, if a lock is taken the code waits on it ... (hmm could you great a grid lock with that Invoke and button press?)

Thanks.
Declaring the variable volatile seems to work.

I do have another problem though.

Passing variables to thread.

I found a seeming solution here which works if the parameters are constants, but in my case I need to pass some data of form control.

So my func would be

void A(int x, int y) {}

And attempting to start it in same fasion causes cross thread error.

ThreadStart starter = delegate { A(this.label1.X, this.label1.Y); };
Thread thread = new Thread(starter);

thread.Start();

It seems as though the thread is already started when it tries to access the form data.

Yeah that works. Also it's weird, sometimes I can delcare like a variable in the Form's thread but can access it on another thread and not risk anything. It's like it's not bound or something

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.