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中实现了对线程的基本控制。