多线程开发:安全的终止工作线程

在多线程开发中,开发人员经常会碰到如何取消工作线程的问题,一般我们不建议使用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;

            }

        }



    }

  


你可能感兴趣的:(多线程)