c# 多线程系列二 自定义线程执行器
看了第一篇文章,多线程系列,看到了在线程执行任务队列有了一定的了解~!
那么今天我来讲讲,怎么样构建通用的自定义线程概念!
线程执行任务,肯定要有目标,但是如果写死了,那么一个线程处理执行职能按照思路处理一类任务,显然不满足我们的实际场景的需求,那么怎么才能创建灵活的线程执行器呢!
首先我们来创建一个任务构造器!
/// <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();
}
}
运行结果图

看到这里是不是很清楚明了呢?这样我们在处理日常任务的时候,不同类型的逻辑或者任务类型,是不是都可以放到一个线程执行呢?
请大家期待我的下一篇文章,为大家讲解,定时器线程执行器,
c# 多线程系列二 自定义线程执行器的更多相关文章
- (Java多线程系列二)线程间同步
Java多线程间同步 1.什么是线程安全 通过一个案例了解线程安全 案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果. 先来看一个线程不安全的例子 class Sell ...
- java多线程系列(二)
对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...
- java多线程系列(二)---对象变量并发访问
对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...
- java多线程编程(二创建线程)
1.概念 因为java是完全面向对象的,所以在java中,我们说的线程,就是Thread类的一个实例对象.所以,一个线程就是一个对象,它有自己字段和方法. 2.创建线程 创建线程有 ...
- Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)
一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会 ...
- java多线程(四)-自定义线程池
当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的 ...
- java多线程(二)-线程的生命周期及线程间通信
一.摘要 当我们将线程创建并start时候,它不会一直占据着cpu执行,而是多个线程间会去执行着这个cpu,此时这些线程就会在多个状态之间进行着切换. 在线程的生命周期中,它会有5种状态,分别为 ...
- java多线程系列六、线程池
一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...
- Java 多线程(二)—— 线程的同步
上文创建多线程买票的例子中注释会出现错票.重票的问题,本文来讲讲如何解决此问题.本文例子:利用多线程模拟 3 个窗口卖票 实现Runnable接口 public class TestThread2 ...
随机推荐
- Linux 网络编程(多路复用)
服务器端代码 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/soc ...
- CSS:谈谈栅格布局
检验前端的一个基本功就是考查他的布局.很久之前圣杯布局风靡一时,这里就由圣杯布局开始,到最流行的bootstrap栅格布局. 圣杯布局 圣杯布局是一种三列布局,两边定宽,中间自适应: * { box- ...
- Java提高篇(二七)-----TreeMap
TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的了解,其实这篇博文的名字叫做:根据红黑树的算法来分析TreeMap的实现,但是为了与Java提高篇系列博文保持一致 ...
- Android Studio2.x版本无法自动关联源码的解决方法
Android Studio2.x版本无法自动关联源码的解决方法 在学习android开发过程中,对于一个不熟悉的类,阅读源码是一个很好的学习方式,使用andorid studio开发工具的SDK M ...
- C++ static
本文主要记录的C++中static的一些内容,内容简单,仅仅作为梳理一下知识,如有错误请留言指出. static的作用 在函数体,一个被声明为static的变量,在这一函数被调用的过程里,其数值维持不 ...
- Atom
http://blog.csdn.net/crper/article/details/45647459
- springmvc下js控制表单提交(表单提交前检验,提交后获取json返回值)
这个问题我搞了四天,终于搞懂.因为对js很不熟悉.郁闷的是后台代码出错总可以设置断点调试,前端js代码出错只能通过浏览器提供一些运行数据来分析,很不习惯. 首先说下逻辑:这是一个注册功能,我希望,注册 ...
- MSP是什么?
本人在项目管理圈儿也算是摸爬滚打了几载,近几年真是各种压力大,看同行们各种参加培训.认证......我也不能懈怠啊,赶紧上网搜搜相关的培训和认证信息,不搜不知道一搜吓一跳.原本只知道PMP和PRINC ...
- 爱上MVC3系列~开发一个站点地图(俗称面包屑)
回到目录 原来早在webform控件时代就有了SiteMap这个东西,而进行MVC时代后,我们也希望有这样一个东西,它为我们提供了不少方便,如很方便的实现页面导航的内容修改,页面导航的样式换肤等. 我 ...
- 【SVN多用户开发】代码冲突&解决办法
SVN是一款集中式的代码存储工具,可以帮助多个用户协同开发同一应用程序. 但是SVN不能完全代替人工操作,有时也需要程序员自己进行沟通确认有效的代码. 下面就简单的看一下,常见的代码冲突以及解决方法. ...