博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于ThreadPool的简单工作管理器
阅读量:7046 次
发布时间:2019-06-28

本文共 5287 字,大约阅读时间需要 17 分钟。

  有这样的场景,淘宝开放平台上有销售订单API,销售订单金额API,商品上下架API,退款API等各种开放的 API,稍微有点规模的商家都会自己开发基于淘宝平台的信息管理系统,里面会涉及到订单管理,采购管理,库存管理,售后管理等,这些管理系统里面的数据都是通过API获取,或者通过API推送到淘宝平台上,这些系统的好处就是避免工作人员直接在淘宝后台进行各项操作。

  基于上面的情况,那么自然会有很多后台程序来跑这些 API,刚开始我是这样设计的。

  

在一个后台程序里面开几个线程,每个线程对应几个API,这样也能够满足日常需求,但是随着业务量增大,会有各种数据或者任务需要处理,这个时候上面的程序也能满足需求,但是每次都要修改程序,然后在发布,实在是有些头疼。后来我就想,能不能开发一个管理平台,来自动管理这些任务,什么时候想停止任务,直接在配置管理网站上点一下按钮,想开启也是一样操作,如果推出这样的一个管理平台,那么像管理这种业务数据的活可以直接丢给店铺管理人员。

  经过一番思考,想到了这样一种方案,先看图。

  

上面的图可以很清晰看出工作管理模型。其实到这个时候,最最关心还是工作管理器的内核到底是怎样设计的?那我就说说我的思路是怎样的。

  首先是工作任务运行时间的设计,因为有的API是需要白天运行的有的是晚上闲时运行的,有的是7*24小时不间断运行的,那么我们可以设计这样的一个枚举,命名WorkType,具体内容是:

public enum WorkType {        ALLWork = 1,        WorkTime = 2,        Morning = 3,        Night = 4 }

 

ALLWork 的运行时间是全天,WorkTime的运行时间是早上9点到晚上22点,Morning的运行时间是凌晨3点到早上9点,Night的运行时间是晚上22点到凌晨3点,相信这几个时间区域很多开发同事都会涉及到的。

  然后是工作线程类WorkThread,将它定义为一个抽象类,里面含有一个抽象方法WorkRun,每一个详细的任务类都会继承WorkThread类,实现抽象方法,也就是说,每个任务的业务处理逻辑都是在WorkRun方法里面实现的。因为上面提到了任务的运行时间区间,那么我们在初始化一个继承WorkThread类的时候,会设置它的运行时间区间。然后在这个抽象类中还还有一个方法,它的作用就是将实现了WorkThread的类丢到ThreadPool里面,看看具体的实现代码。

public abstract class WorkThread {        private int index;        public WorkThread(int Step,WorkType worktype)        {            this.WorkType = worktype;            this.Step = Step;            this.index = Step;        }        public int Step { get;  set; }        public WorkType WorkType { get;  set; }        public bool HasWork        {            get            {                bool result = false;                switch (WorkType)                {                    case WorkType.Morning:                        result = index == Step &&  3<=DateTime.Now.Hour && DateTime.Now.Hour<=9 ? true : false;                        break;                    case WorkType.WorkTime:                        result = index == Step && 9 <= DateTime.Now.Hour && DateTime.Now.Hour <= 22 ? true : false;                        break;                    case WorkType.Night:                        result = index == Step && 22 <= DateTime.Now.Hour && DateTime.Now.Hour <= 3 ? true : false;                        break;                    case WorkType.ALLWork:                    default:                        result = index == Step  ? true : false;                        break;                }                return result;            }        }        public abstract void WorkRun(object ob);               public void Run()        {            ThreadPool.QueueUserWorkItem(new WaitCallback(WorkRun));            index = 0;        }        public void AddStep()        {            index += 1;        } }

  那么具体的任务类如下。

public class TestA : WorkThread {        public TestA(int step, WorkType type)            : base(step, type)        { }        public override void WorkRun(object ob)        {            Console.WriteLine(string.Format("我是A小姐,我开始工作了。时间:{0}", DateTime.Now));        } }

  其实到这里了,有的人会想到,那我们怎么来管理这些WorkThread类了,这里我们专门有一个类来管理WorkThread,这里命名为WorkManager。这个类里面的结构就相当简单了。看到上面的模型图,可以猜出一些端倪。里面专门定义了一个字典项,用来存储每一个WorkThread,它是ConcurrentDictionary,表示可由多个线程同时访问的键值对的线程安全集合。管理类里面还定义了4个方法,增加删除WorkThread,开始结束WorkThread。具体看下面的代码。

public class WorkManager{        static readonly ConcurrentDictionary
WorkCache = new ConcurrentDictionary
(); public int WorkCount { get { return WorkCache.Count; } } public void AddWork(WorkThread workThread) { WorkCache.TryAdd(workThread.GetType().FullName, workThread); } public void RemoveWork(string workThreadId) { var obj = WorkCache[workThreadId]; if(obj != null) WorkCache.TryRemove(workThreadId, out obj); } public void StartWork() { Action action = () => { while (true) { foreach (KeyValuePair
work in WorkCache) { if (work.Value.HasWork) { work.Value.Run(); } else { work.Value.AddStep(); } } Thread.Sleep(5000); } }; action.BeginInvoke(cb => action.EndInvoke(cb), null); } public void EndWork() { Action action = () => { WorkCache.Clear(); }; action.BeginInvoke(cb => action.EndInvoke(cb), null); }}

代码是不是很简单,到这里位置,工作管理的内核代码全部上完了,那我们该怎么调用了,看看下面调用代码。

Console.Title = "工作管理器";            WorkManager manager = new WorkManager();            manager.AddWork(new TestA(1, WorkType.ALLWork));            manager.AddWork(new TestB(1, WorkType.ALLWork));            manager.StartWork();            Console.WriteLine("1.全部开始工作");            Thread.Sleep(15 * 1000);            manager.EndWork();            Console.WriteLine("2.全部卸载");            Thread.Sleep(10 * 1000);            manager.AddWork(new TestB(1, WorkType.ALLWork));            Console.WriteLine("3.加入B");            Console.Read();

看一下运行效果图:

  大家看完之后是不是觉得很简单,不过有什么疑问可以在这里留言,谢谢。

  示例代码下载:

 

转载于:https://www.cnblogs.com/wucj/archive/2013/05/26/2440335.html

你可能感兴趣的文章
yii表单
查看>>
惊艳的HTML5动画特效及源码
查看>>
2014年QS世界大学排名
查看>>
面向对象程序设计与面向过程程序设计解析
查看>>
公网服务 基础知识
查看>>
vs必备快捷键整理
查看>>
Android 广播(内部类)
查看>>
[AX 2012] Woker user request
查看>>
Android-LinearLayout布局技巧(二)
查看>>
黄页js-sdk开发总结分享
查看>>
程序员应该知道的10大编程格言
查看>>
EasyUI的combobox组件Chrome浏览器不兼容问题解决办法
查看>>
JAVA实现二叉树
查看>>
如何制作iso文件
查看>>
构建openssl debug版
查看>>
jquery 的datatables插件问题
查看>>
Putty密钥(PrivateKey)导入SecureCRT
查看>>
移动环境下DNS解析失败后的优化方案
查看>>
TeeChart的最小步长和最大步长
查看>>
spring+springMVC中使用@Transcational方式管理事务的必须要配的东西。
查看>>