启动和停止(强制)线程作业

时间:2011-02-28 18:46:26

标签: c# .net multithreading

我想知道一种正确的方法来启动和停止强制和非强制的线程作业。这是停止线程的正确方法吗?

    public class ProcessDataJob : IJob
    {
        private ConcurrentQueue<byte[]> _dataQueue = new ConcurrentQueue<byte[]>();
        private volatile bool _stop = false;
        private volatile bool _forceStop = false;
        private Thread _thread;
        private int _timeOut = 1000;

        public void Start()
        {
            _stop = false;
            _forceStop = false;

            _thread = new Thread(ProcessData);
            _thread.Start();
        }

        private void ProcessData()
        {
            while (!_stop || _dataQueue.Count > 0)
            {
                if(_forceStop) return;

                byte[] data;
                if(_dataQueue.TryDequeue(data))
                {
                   //Process data
                   //.....//
                }
            }
        }

        public void Stop(bool force)
        {
            _stop = true;
            _forceStop = force;
            _thread.Join(_timeOut); 
        }

        public void Enqueue(byte[] data)
        {
            _dataQueue.Enqueue(data);
        }
    }

3 个答案:

答案 0 :(得分:7)

没有正确的方式来强行杀死一个帖子。

有几种方法可以做到,但它们都不是正确的

只有当你需要终止程序,或者卸载包含该线程的appdomain时,你才应该强行杀死一个线程,并且不关心任何在损坏/坏/锁定状态下悬空的数据结构,因为它们也会在短时间内消失。

互联网上有很多关于Thread.Abort是多么糟糕/邪恶的建议,所以不要这样做。

相反,编写适当的协作线程。线程应该自己检查一个标志(事件,挥发性bool字段等),然后在很好地要求时自愿退出。

这是正确的方式。

答案 1 :(得分:1)

这是我过去做过的方式,但有一点不同。我的线程在过去意外地挂起,这意味着你的那个循环没有带回答。为了解决这个问题,我有所有使用类的线程,像你的一样,注册一个'经理'类,负责参与像Forced Stop这样的关键事情。线程类具有对管理器的引用,并且当强制停止时,它调用管理器上的方法,该方法实际上是计时器。如果在计时器关闭时,线程类没有将状态标志设置为STOPPED,则管理器会对其进行中止。

对我来说关键的不仅仅是呼叫'停止',而是确认'停止'已经发生,并且理解它将是一个非确定性的时间量但是'经过一段合理的时间'之后我应该放弃并继续前进。

答案 2 :(得分:0)

您可以使用.NET ThreadPool类,这样您就不必自己处理堆栈。