专注

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在多线程开发中,开发人员经常会碰到如何取消工作线程的问题,一般我们不建议使用Thread.Abort()来终止线程,MSDN中Thread.Abort方法的说明:“在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。” 所以结束线程最好是让线程主动退出,可以通过变量、事件等方式通知线程。

以下代码是从书本上看到,非常好的解决了如何关闭工作线程的问题:

 public class WorkerThread : IDisposable
    {
        ManualResetEvent m_ThreadHandle;
        Thread m_ThreadObj;
        bool m_EndLoop;
        Mutex m_EndLoopMutex;

        public WorkerThread()
        {
            m_EndLoop = false;
            m_ThreadObj = null;
            m_EndLoopMutex = new Mutex();
            m_ThreadHandle = new ManualResetEvent(false);
            m_ThreadObj = new Thread(Run);
            Name = "Worker Thread";
        }

        public WorkerThread(bool autoStart)
            : this()
        {
            if (autoStart)
            {
                Start();
            }
        }

        public void Start()
        {
            Debug.Assert(m_ThreadObj != null);
            Debug.Assert(m_ThreadObj.IsAlive == false);
            //m_ThreadObj.Start();
        }

        void Run()
        {
            try
            {
                int i = 0;
                while (EndLoop == false)
                {
                    Trace.WriteLine(string.Format("THread is alive, Counter is {0}", i));
                    i++;
                }
            }
           finally
            {

                m_ThreadHandle.Set();
            }
        }

        public void Dispose()
        {
            Kill();
        }

        public void Kill()
        {
            Debug.Assert(m_ThreadObj != null);
            if(IsAlive == false)
            {
                return;
            }

            EndLoop = true;
            Join();
            m_EndLoopMutex.Close();
            m_ThreadHandle.Close();
        }

        public void Join()
        {
            Join(Timeout.Infinite);
        }

        public bool Join(int millisecondsTimeout)
        {
            TimeSpan timeout = TimeSpan.FromMilliseconds(millisecondsTimeout);
            return Join(timeout);
        }

        public bool Join(TimeSpan timeout)
        {
            Debug.Assert(m_ThreadObj != null);
            if (IsAlive == false)
            {
                return true;
            }

            Debug.Assert(Thread.CurrentThread.ManagedThreadId != m_ThreadObj.ManagedThreadId);
            return m_ThreadObj.Join(timeout);
        }

        public string Name
        {
            get
            {
                return m_ThreadObj.Name;
            }
            set
            {
                m_ThreadObj.Name = value;
            }
        }

        public bool IsAlive
        {
            get
            {
                Debug.Assert(m_ThreadObj != null);
                bool handleSignaled = m_ThreadHandle.WaitOne(0, true);
                //如果代码已经执行完毕,但工作线程的IsAlive仍为true,循环等待
                while(handleSignaled == m_ThreadObj.IsAlive)
                {
                    Thread.Sleep(0);
                }
                return m_ThreadObj.IsAlive;
            }
        }
        public override int GetHashCode()
        {
            return m_ThreadObj.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            return m_ThreadObj.Equals(obj);
        }

        public int ManagedThreadId
        {
            get
            {
                return m_ThreadObj.ManagedThreadId;
            }
        }

        public Thread Thread
        {
            get
            {
                return m_ThreadObj;
            }
        }

        protected bool EndLoop
        {
            set
            {
                m_EndLoopMutex.WaitOne();
                m_EndLoop = value;
                m_EndLoopMutex.ReleaseMutex();
            }
            get
            {
                bool result = false;
                m_EndLoopMutex.WaitOne();
                result = m_EndLoop;
                m_EndLoopMutex.ReleaseMutex();
                return result;
            }
        }

        public WaitHandle Handle
        {
            get
            {
                return m_ThreadHandle;
            }
        }

    }

  


posted on 2011-12-29 17:12  中金黄金  阅读(382)  评论(0编辑  收藏  举报