项目需要,有很多操作需要在线程中执行,而且启动线程的结构完全相同,因此想到用父子类并重写基类方法的方式实现,于是啪啪啪就写了
不正确-父类
using System; using System.Threading; namespace HuluChajian.ThreadHelper { internal class ThreadHelper { static ThreadHelper _instance; public static ThreadHelper Instance { get { return _instance == null ? _instance = new ThreadHelper() : _instance; } } /// <summary>标识线程是否已经启动,已经启动值为true</summary> bool isStart = false; /// <summary>启动线程[一般情况下不重写此方法]</summary> public virtual void Start() { if (isStart) { return; }//已经启动过不能再次启动,直接返回. isStart = true; new Thread(() => { while (isStart) { Internal_Start(); } }).Start(); } /// <summary>启动线程需要调用的自定义方法</summary> protected virtual void Internal_Start() { Console.WriteLine("ThreadHelper"); Thread.Sleep(1000);//每隔1秒执行一次 } /// <summary>停止线程</summary> public void Stop() { isStart = false; Internal_Stop(); } /// <summary>停止线程需要调用的自定义方法</summary> protected virtual void Internal_Stop() { Console.WriteLine("ThreadHelper---Stop"); } } }
不正确-子类
using System; using System.Threading; namespace HuluChajian.ThreadHelper { /// <summary> /// 守护进程的保活线程,保持update.exe意外关闭后能自动重启 /// </summary> internal class ThreadProtectProcess : ThreadHelper { protected override void Internal_Start() { Console.WriteLine("ThreadProtectProcess"); Thread.Sleep(1000);//每隔1秒执行一次 } protected override void Internal_Stop() { Console.WriteLine("ThreadProtectProcess---Stop"); } } }
调用测试
using HuluChajian.ThreadHelper; using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { ThreadProtectProcess.Instance.Start(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { ThreadProtectProcess.Instance.Stop(); } } }
首先想到的是将return _instance == null ? _instance = new ThreadHelper() : _instance;
代码中的new ThreadHelper()
改为虚方法,在子类中重写,一测试发现这个是静态属性中内容,方法也必须是静态方法,而静态成员不能标记为override、virtual、abstract。问了同事们,也没有哪个知道,后来还是在博客园找到一篇文章才解决这个单例实例化问题,就是使用反射实例化成子类,代码如下
正确-父类-使用泛型、反射
using System; using System.Threading; namespace HuluChajian.ThreadHelper { internal class ThreadHelper<T> where T : class { static T _instance; public static T Instance { get { return _instance == null ? _instance = (T)System.Reflection.Assembly.GetAssembly(typeof(T)).CreateInstance(typeof(T).ToString()) : _instance; } } /// <summary>标识线程是否已经启动,已经启动值为true</summary> bool isStart = false; /// <summary>启动线程[一般情况下不重写此方法]</summary> public virtual void Start() { if (isStart) { return; }//已经启动过不能再次启动,直接返回. isStart = true; new Thread(() => { while (isStart) { Internal_Start(); } }).Start(); } /// <summary>启动线程需要调用的自定义方法</summary> protected virtual void Internal_Start() { Console.WriteLine("ThreadHelper"); Thread.Sleep(1000);//每隔1秒执行一次 } /// <summary>停止线程</summary> public void Stop() { isStart = false; Internal_Stop(); } /// <summary>停止线程需要调用的自定义方法</summary> protected virtual void Internal_Stop() { Console.WriteLine("ThreadHelper---Stop"); } } }
正确-子类
using System; using System.Threading; namespace HuluChajian.ThreadHelper { /// <summary> /// 守护进程的保活线程,保持update.exe意外关闭后能自动重启 /// </summary> internal class ThreadProtectProcess : ThreadHelper<ThreadProtectProcess> { protected override void Internal_Start() { Console.WriteLine("ThreadProtectProcess"); Thread.Sleep(1000);//每隔1秒执行一次 } protected override void Internal_Stop() { Console.WriteLine("ThreadProtectProcess---Stop"); } } }
ThreadProtectProcess.Instance.Start();
后,会每隔1秒在vs输出窗口显示 ThreadProtectProcess 字符串,调用ThreadProtectProcess.Instance.Stop();
后输出 ThreadProtectProcess---Stop字符串并且不再输出 ThreadProtectProcess字符串,线程结束
文章评论