看了第一篇文章,多线程系列,看到了在线程执行任务队列有了一定的了解~!
那么今天我来讲讲,怎么样构建通用的自定义线程概念!
线程执行任务,肯定要有目标,但是如果写死了,那么一个线程处理执行职能按照思路处理一类任务,显然不满足我们的实际场景的需求,那么怎么才能创建灵活的线程执行器呢!
首先我们来创建一个任务构造器!
/// <summary> /// 线程模型执行任务 基类 /// </summary> public abstract class BaseTask { /// <summary> /// 任务ID /// </summary> public long TID { get; set; } /// <summary> /// 任务名称 /// </summary> public string TName { get; set; } /// <summary> /// 线程模型任务 /// </summary> public abstract void Run(); public override string ToString() { return "Task<" + this.TName + "(" + TID + ")>"; } }
看到这里,可能不会明白,这么写法的意义在哪里呢?
那么我们再来自定义线程的执行器
/// <summary> /// 定义自定义线程模型 /// </summary> public abstract class BaseThread<T> where T : BaseTask { //执行线程 Thread _Thread; //通知一个或多个正在等待的线程已发生事件 ManualResetEvent mre = new ManualResetEvent(false); //线程安全的队列 System.Collections.Concurrent.ConcurrentQueue<T> cqueue = new System.Collections.Concurrent.ConcurrentQueue<T>(); /// <summary> /// 自定义线程ID; /// </summary> public long TID { get; set; } public static bool IsRuning = true; /// <summary> /// 初始化 /// </summary> /// <param name="tName">线程的名称</param> public BaseThread(string tName) { _Thread = new Thread(Runing); _Thread.Name = tName; _Thread.Start(); } //模拟新增任务 public void AddTask(T task) { //添加任务到队列 cqueue.Enqueue(task); //唤醒所有相关的挂起线程 mre.Set(); } void Runing() { //主循环 服务器运行标识 while (IsRuning) { //如果是空则继续等待 服务器运行标识 while (cqueue.IsEmpty && IsRuning) { //重置线程暂停状态 mre.Reset(); //这个操作是以便服务器需要停止操作, //如果停止调用线程的Thread.Abort()是会导致处理队列任务丢失 mre.WaitOne(); #if DEBUG //为了方便测试信息打印的暂停信息 Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:ffff") + " : " + Thread.CurrentThread.Name + " Status Sleep"); #endif } T t; //取出队列任务 if (cqueue.TryDequeue(out t)) { Runing(t); } } } /// <summary> /// 设置运行方法为虚方法,方便子函数覆盖 /// </summary> protected virtual void Runing(T run) { try { //执行任务 run.Run(); //打印任务信息 Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:ffff") + " : " + Thread.CurrentThread.Name + " Action:" + run.ToString()); } catch (Exception ex) { //打印任务信息 Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:ffff") + " : " + Thread.CurrentThread.Name + " Action:" + run.ToString() + " Exception:" + ex); } } }
看到这里是不是比较清楚了?这样我们定义的线程是不是能完成多不同类型的任务呢?
是不是可以做到一个线程执行和处理不同类型的任务呢?
接下来我们创建类型的实现类
任务实现类1
/// <summary> /// 测试任务 /// </summary> public class TestTask : BaseTask { public override void Run() { Console.WriteLine("我只是用来测试的"); } }
任务实现类2
public class TestTask1 : BaseTask { /// <summary> /// 执行任务 /// </summary> public Action Test { get; set; } public override void Run() { if (Test != null) { Test(); } Console.WriteLine("我只是用来测试的"); } }
线程的实现类
/// <summary> /// 测试线程 /// </summary> public class TestThread : BaseThread<BaseTask> { public TestThread() : base("TestThread") { } }
接下来我们看看测试效果
class Program { static void Main(string[] args) { TestThread tt = new TestThread(); tt.AddTask(, TName = "测试1" }); tt.AddTask(, TName = "测试2" }); tt.AddTask(, TName = ); }) }); tt.AddTask(, TName = "测试4" }); Console.ReadLine(); } }
运行结果图
看到这里是不是很清楚明了呢?这样我们在处理日常任务的时候,不同类型的逻辑或者任务类型,是不是都可以放到一个线程执行呢?
请大家期待我的下一篇文章,为大家讲解,定时器线程执行器,