C#中 一个多线程框架

C#提供了丰富的多线程操作,为编程带来了极大的便利,但如果使用不当也会带来各种各样的麻烦。

这里把C#中多线的操作进行了一下简单的封装,使它对外提供的接口简洁,易于控制。

 

保留一下的代码片段,以备日后查用。

BaseThread基类,线程派生类可以继承这个基类,并且实现自己的Run方法。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace BaseThread
{
    public class BaseThread
    {
        public enum ThreadStatus
        {
            CREATED,
            RUNNING,
            STOPED,
        };

        private int m_Tid;
        private bool m_IsAlive;
        private ThreadStatus m_Status;
        private Thread m_WorkingThread;

        private static void WorkFunction(object arg)
        {
            try
            {
                System.Diagnostics.Trace.WriteLine("BaseThread::WorkFunction {");
                ((BaseThread)arg).Run();
                System.Diagnostics.Trace.WriteLine("BaseThread::WorkFunction }");
            }
            catch (ThreadAbortException abt_ex)
            {
                System.Diagnostics.Trace.WriteLine("BaseThread::WorkFunction ThreadAbortException " + abt_ex.ToString());
                Thread.ResetAbort();
            }
            catch (ThreadInterruptedException int_ex)
            {
                System.Diagnostics.Trace.WriteLine("BaseThread::WorkFunction ThreadAbortException " + int_ex.ToString());
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine("BaseThread::WorkFunction Exception " +ex.ToString());
            }
            finally
            {
                ((BaseThread)arg).Status = ThreadStatus.STOPED;
                m_IsAlive = false;
                m_Tid = -1;
            }
        }

        public BaseThread()
        {
            m_WorkingThread = new Thread(WorkFunction);
            m_Tid = -1;
            m_IsAlive = false;
            m_Status = ThreadStatus.CREATED;
        }

        public int Start()
        {
            try
            {
                System.Diagnostics.Trace.WriteLine("DLx Framework BaseThread Start() {");
                m_WorkingThread.Start(this);
                m_Tid = m_WorkingThread.ManagedThreadId;
                m_IsAlive = true;
                m_Status = ThreadStatus.RUNNING;

                System.Diagnostics.Trace.WriteLine("DLx Framework BaseThread Start() }");
            }
            catch(Exception ex)
            {
                System.Diagnostics.Trace.WriteLine("DLx Framework BaseThread Start() Get an exception: " + ex.ToString());
                m_Tid = -1;
                m_IsAlive = false;
                m_Status = ThreadStatus.STOPED;
            }
            return 0;
        }

        public int Stop(int timeout)
        {
            System.Diagnostics.Trace.WriteLine("DLx Framework BaseThread Stop {");
            try
            {
                if (m_IsAlive)
                {
                    System.Diagnostics.Trace.WriteLine("BaseThread Stop: Thread is alive");
                    m_IsAlive = false;

                    if (timeout > 0)
                    {
                        if (!m_WorkingThread.Join(timeout))
                        {
                            System.Diagnostics.Trace.WriteLine("BaseThread Stop: Join failed, m_WorkingThread.Abort {");
                            m_IsAlive = false;
                            m_WorkingThread.Abort();
                            System.Diagnostics.Trace.WriteLine("BaseThread Stop: Join failed, m_WorkingThread.Abort }");
                        }
                    }
                    else
                    {
                        if (!m_WorkingThread.Join(3000))
                        {
                            System.Diagnostics.Trace.WriteLine("BaseThread Stop: Join Timer default = 3000 failed, m_WorkingThread.Abort {");
                            m_IsAlive = false;
                            m_WorkingThread.Abort();
                            System.Diagnostics.Trace.WriteLine("BaseThread Stop: Join Timer default = 3000 failed, m_WorkingThread.Abort }");
                        }
                    }
                }
                else
                {
                    System.Diagnostics.Trace.WriteLine("BaseThread Stop: Thread is NOT alive");

                    if (m_WorkingThread != null)
                    {
                        System.Diagnostics.Trace.WriteLine("BaseThread Stop: Thread status is UNUSUAL");
                        if (m_WorkingThread.IsAlive)
                        {
                            System.Diagnostics.Trace.WriteLine("BaseThread Stop: Force to ABOTR ");
                            m_WorkingThread.Abort();
                        }
                    }
                }
                m_WorkingThread = null;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine("BaseThread Stop: " + ex.ToString());
            }

            System.Diagnostics.Trace.WriteLine("DLx Framework BaseThread Stop }");
            return 0;
        }
        
        public int Tid
        {
            get { return m_Tid; }    
        }

        public bool IsAlive
        {
            get { return m_IsAlive; }
        }

        public ThreadStatus Status
        {
            get { return m_Status; }
            set { m_Status = value; }
        }


        public virtual void Run(){}

        ~BaseThread()
        {
            if (m_WorkingThread != null)
            {
                System.Diagnostics.Trace.WriteLine("~BaseThread: Thread status is UNUSUAL");
                if (m_WorkingThread.IsAlive)
                {
                    System.Diagnostics.Trace.WriteLine("~BaseThread: Force to ABOTR ");
                    m_WorkingThread.Abort();
                }
                m_WorkingThread = null;
            }
        }
    }
}

  子类继承 BaseThread,它的Run函数很简单,只是打印数字。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DLxFramework;


namespace UseThreadBase
{
    public class Worker : BaseThread
    {
        public Worker()
        {}

        private int m_i = 0;
        public override void Run()
        {
            while (IsAlive)
            {
                Console.WriteLine("Worker : " + m_i++);
            }
        }

        public int Value
        {
            get { return m_i; }
        }
    }
}

  Main函数启动和停止工作线程。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UseThreadBase
{
    class Program
    {
        static void Main(string[] args)
        {
            Worker work = new Worker();

            work.Start();

            System.Threading.Thread.Sleep(5000);

            work.Stop(2000);

        }
    }
}

  

在整个的例子中,业务处理的工作单元并不需要去关注线程的启动,停止和异常处理等细节。它只需要重载Run函数,并添加自己的工作内容即可。

BaseThread中实现了对线程的基本控制。

posted @ 2016-08-08 22:22  Null98  阅读(1087)  评论(1编辑  收藏  举报