简体   繁体   中英

C# Start and Stop same thread using 2 different buttons

I have created a simple form home and there is another file Mouse_Tracking.cs .

Mouse_Tracking.cs class is a thread class. I want to start and stop that thread using two different button click in home form.

How can I do this ?

Main form:

namespace computers
{
    public partial class home : Form
    {
        public home()
        {
            InitializeComponent();
        }

        private void btn_start_Click(object sender, EventArgs e)
        {
            var mst = new Mouse_Tracking();

            Thread thread1 = new Thread(new ThreadStart(mst.run));

            thread1.Start();
        }

        private void btn_stop_Click(object sender, EventArgs e)
        {
            //Here I want to stop "thread1"
        }
    }
}

Computers class:

namespace computers
{
    public class Mouse_Tracking
    {
        public void run()
        {
        // Some method goes here
        }
}

You shouldn't kill threads from the outside. Instead, you should gently ask your thread to terminate, and in your thread you should respond to that request and return from the thread procedure.

You could use an event for that. Eg add the following to your form class:

AutoResetEvent evtThreadShouldStop = new AutoResetEvent();

In your run method, check if the svtThreadShouldStop event is set every 0.1-1 seconds, if it's set, return from the thread function, eg if( evtThreadShouldStop.WaitOne( 0 ) ) return;

And in your btn_stop_Click call evtThreadShouldStop.Set();

PS It's rarely a good decision to create your own thread: creating and destroying threads is expensive. The runtime already has the thread pool you can use for your own background processing. To post your background task to a pool thread instead use eg ThreadPool.QueueUserWorkItem method. You can use same technique with AutoResetEvent to request task termination.

PPS The name of the Mouse_Tracking class suggest you're trying to interact with mouse from the background thread? You can't do that: you can only interact with the GUI including mouse and keyboard from the GUI thread.

Here is an example of what Soonts has suggested. It's quite old-style solution but it's simple and will work fine. But there is a number of other approaches. You can use BackgroundWorker or TPL ( Task class), each of which have own thread stop mechanisms.

And I believe that it's ok to create own thread without using existing thread pool if you don't need to do it too often.

public class Mouse_Tracking
{
    private ManualResetEvent _stopEvent = new ManualResetEvent(false);

    public void stop()
    {
        _stopEvent.Set();
    }

    public void run()
    {
        while (true)
        {
            if (_stopEvent.WaitOne(0))
            {
                //Console.WriteLine("stop");
                // handle stop
                return;
            }

            //Console.WriteLine("action!");

            // some actions
            Thread.Sleep(1000);
        }
    }
}

Sometimes its quite difficult to maintain the thread. You can achieve it by using BackgroundWorker class. You will get complete demonstration on how to use it is here Stop Watch Using Background Worker . I hope it will be useful.

You could use a class like this for controlling your thread(s):

class ThreadController {
    private Thread _thread;

    public void Start(ThreadStart start) {
        if (_thread == null || !_thread.IsAlive) {
            _thread = new Thread(start);
            _thread.Start();
        }
    }

    public void Stop() {
        if (_thread != null && _thread.IsAlive) {
            _thread.Interrupt(); // Use _thread.Abort() instead, if your thread does not wait for events.
            _thread = null;
        }
    }
}

Then use:

public partial class home : Form
{
    public home()
    {
        InitializeComponent();
        _thread = new ThreadController();
    }

    private readonly ThreadController _thread;

    private void btn_start_Click(object sender, EventArgs e)
    {
        var mst = new Mouse_Tracking();
        _thread.Start(mst.run);
    }

    private void btn_stop_Click(object sender, EventArgs e)
    {
        _thread.Stop();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM