项目需要,有很多操作需要在线程中执行,而且启动线程的结构完全相同,因此想到用父子类并重写基类方法的方式实现,于是啪啪啪就写了
不正确-父类
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字符串,线程结束