两年前,刚到公司接触了Quartz.对它好奇不已,有不少疑问和好奇
于是乎问我们老大:他是怎么实现的?
老大说:是用底层线程做的
就没有然后了,我当时决定要下载源码来看看,不信看不懂!
https://github.com/quartznet/quartznet
Ok,万事具备开始下断点调试
过了一会,断点呢?于是第一次宣布放弃
时间过了一年。。。。。。
我以为我已经够能看懂这个开源项目的地步了,正好当时需要基于此开发一个可持续的,自动化的,可配置的Job运行站点
通过AppDomain的简单加载,卸载进行实现,最后是完成了
去年和前年一样,下断点,调试,最终还是把断点丢了。不同的是去年多丢了几次。。。
时间到了今年,是时候了结了!!
断点还是要的。
最终是这么来的:
1.使用红门(Red Gate)的性能测试工具 ANTS附加进程跟踪,分两步,1是启动时,2是启动后,
哈哈,启动的执行步骤在ANTS下只剩一条内裤
启动后调度器调度的过程更是内裤都没了
2.有了执行过程那下起断点来,哪里不会点哪里,
1.启动时主要工作:初始化调度器-》初始化调度器线程,并开始跑内部是Thread.同时初始化配置或者默认的10个线程的自定义线程池(两个回路链表,一个是空闲链表,一个是繁忙链表),每个线程While(True),确实是这样的
2.启动完成后,代码会调研ScacheduleJob,这是是将任务,触发器存储至RamJobStore(一种存储方式)
3.之后调度器线程通过存储的触发器计算将要执行的Job,如果有的话通过JobRunShellFactory创建JobRunShell,其实就是实例化我们实现的IJob的类,以及其他一些信息。
4.调度器线程调用线程池执行任务方法,获取空闲链表的第一个,加入到繁忙链表中,并关联上刚刚获取到的IJob实例。
5.空闲工作线程一直在While(true),当调用了这个方法后
SimpleThreadPool.cs的Run方法
WorkerThread类的Run方法
将直接开跑,执行我们的任务。
以上是花了一下午的结果,当然还有很多其他内容。包括它的抽象反射工程模式,以及我吐槽它的一些命名,还有对Thread的掌控,是学习Thread的不错的开源项目
不止想和大家分享下QuartzC#的实现,还有就是这个过程,希望能让自己少走弯路,从大方向入手或许能更有效的掌控和了解全局