C#使用2个不同的按钮启动和停止相同的线程

时间:2014-08-03 06:46:28

标签: c# .net multithreading class methods

我创建了一个简单的表单home,还有另一个文件Mouse_Tracking.cs

Mouse_Tracking.cs类是一个线程类。我想在home表单中使用两个不同的按钮单击启动和停止该线程。

我该怎么做?

主要形式:

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上课:

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

4 个答案:

答案 0 :(得分:2)

你不应该从外面杀死线程。相反,您应该轻轻地要求您的线程终止,并且在您的线程中,您应该响应该请求并从线程过程返回。

你可以使用一个事件。例如。将以下内容添加到表单类:

AutoResetEvent evtThreadShouldStop = new AutoResetEvent();

在你的run方法中,检查svtThreadShouldStop事件是否每0.1-1秒设置一次,如果已设置,则从线程函数返回,例如if( evtThreadShouldStop.WaitOne( 0 ) ) return;

在你的btn_stop_Click中调用evtThreadShouldStop.Set();

P.S。创建自己的线程很少是一个好的决定:创建和销毁线程是昂贵的。运行时已经有了可用于自己后台处理的线程池。要将后台任务发布到池线程,请使用例如ThreadPool.QueueUserWorkItem方法。您可以使用与AutoResetEvent相同的技术来请求任务终止。

P.P.S。 Mouse_Tracking类的名称建议您尝试与后台线程中的鼠标进行交互?你不能这样做:你只能通过GUI线程与GUI交互,包括鼠标和键盘。

答案 1 :(得分:2)

以下是Soonts建议的一个例子。这是相当旧式的解决方案,但它很简单,并且工作正常。但是还有许多其他方法。您可以使用BackgroundWorker或TPL(Task类),每个类都有自己的线程停止机制。

我相信如果您不需要经常使用现有的线程池,那么创建自己的线程是可以的。

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);
        }
    }
}

答案 2 :(得分:0)

有时维护线程非常困难。您可以使用BackgroundWorker类来实现它。您将在Stop Watch Using Background Worker获得有关如何使用它的完整演示。我希望它会有用。

答案 3 :(得分:0)

你可以使用这样的类来控制你的线程:

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;
        }
    }
}

然后使用:

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();
    }
}