新生命组件XAgent使用心得

时间:2023-02-04 17:15:08

1.简单介绍

XAgent为大石头带领下的新生命团队自己开发的一个.Net下的常用的Windows服务管理组件利器,通过在控制台中简单的输入1,2,3,4,5等数字可以实现一步安装、卸载WindowsService以及单步调试和循环调试、服务停止,重启、运行,用起来很方便。看效果(具体使用方法可以去XAgent官网查看):

新生命组件XAgent使用心得

2.当前使用场景介绍及实现

我的这个项目下面有很多控制台应用程序需要运行,平时部署很麻烦,不方便管理。我的想法是把这些程序以插件的形式放到一个应用程序中运行管理。这里写了一个Ijob接口。看代码:

Ijob相关代码

   /// <summary>工作接口</summary>
public interface IJob
{
/// <summary>
/// 工作组件顺序
/// </summary>
int Sort { get; set; } /// <summary>
/// 间隔时间
/// </summary>
int JobInterval { get; set; } /// <summary>启动</summary>
/// <returns></returns>
bool Start(); /// <summary>停止</summary>
/// <returns></returns>
bool Stop(); /// <summary>工作</summary>
bool Work(); //void WriteLog(string format, params object[] args);
} /// <summary>基础工作组件</summary>
public class Job : IJob
{
///// <summary>
///// 是否执行
///// </summary>
//public bool IsExcute { get; set; } public Job()
{
Sort = ;
DisplayName = "基础工作组件";
JobInterval = ; //默认60秒
//IsExcute = true;//默认执行
} /// <summary>工作组件名</summary>
public virtual string DisplayName { get; set; } /// <summary>工作组件顺序</summary>
public virtual int Sort { get; set; } /// <summary>
/// 时间间隔
/// </summary>
public int JobInterval { get; set; } /// <summary>启动</summary>
public virtual bool Start()
{
WriteLog("开始工作");
return false;
} /// <summary>停止</summary>
/// <returns></returns>
public virtual bool Stop()
{
WriteLog("停止工作");
return false;
} /// <summary>工作</summary>
public virtual bool Work()
{
WriteLog("正在运行");
return false;
} public virtual void WriteLog(string format, params object[] args)
{
//XTrace.WriteLine("[" + this.GetType() + "] [" + DisplayName + "] " + format, args);
XTrace.WriteLine("[" + DisplayName + "] " + format, args);
}
  public static class JobHelper
{
static readonly List<Type> _hasInited = new List<Type>(); private static List<IJob> op_cache = new List<IJob>(); /// <summary>所有工作组件</summary>
public static List<IJob> Works
{
get
{
var list = LoadWork();
foreach (var item in list)
{
EnsureInit(item);
}
op_cache = op_cache.OrderBy(j => j.Sort).ToList();
return op_cache;
}
} /// <summary>确保实体类已经执行完静态构造函数,因为那里实在是太容易导致死锁了</summary>
/// <param name="type">类型</param>
internal static void EnsureInit(Type type)
{
if (_hasInited.Contains(type)) return;
// 先实例化,在锁里面添加到列表但不实例化,避免实体类的实例化过程中访问CreateOperate导致死锁产生
var item = type.CreateInstance();
lock (_hasInited)
// 如果这里锁定_hasInited,还是有可能死锁,因为可能实体类A的静态构造函数中可能导致调用另一个实体类的EnsureInit
// 其实我们这里加锁的目的,本来就是为了避免重复添加同一个type而已
//lock ("_hasInited" + type.FullName)
{
if (_hasInited.Contains(type)) return; if (op_cache.Contains(item as IJob)) return;
op_cache.Add(item as IJob); //type.CreateInstance();
_hasInited.Add(type);
}
} /// <summary>列出所有工作接口</summary>
/// <returns></returns>
public static List<Type> LoadWork()
{
return typeof (IJob).GetAllSubclasses(true).ToList();
}
}

确保所有的工作组件继承Job类,重写其中的方法,将一些需要配置的属性做成xml进行管理。废话不说看代码:

这是其中一个工作插件

    public HourStatisticsWork()
{ DisplayName = "小时统计组件";
Sort = ; if (WorkSetting.Current.HourStatisticsEnable)
{
JobInterval = WorkSetting.Current.HourStatisticsInterval;
}
else
{
JobInterval = -; //禁用此组件
}
} public override bool Work()
{
StartWork();
return base.Work();
}
public override bool Stop()
{
if (_HourTimer != null)
{
_HourTimer.Dispose();
}
return base.Stop();
}
public void StartWork()
{
try
{
// Console.WriteLine("当前时间{0}",DateTime.Now);
//var time = WorkSetting.Current.HourStatisticsInterval;
//// 定时器一分钟后启动
//if (_HourTimer == null)
// _HourTimer = new TimerX(obj =>
// { // StartWork();
// }, null, 3 * 1000, time);
DateTime dt = DateTime.Now.AddHours(-);
cyStatistics(dt);
sccStatistics(dt);
ccStatistics(dt);
jcStatistics(dt);
mfStatistics(dt);
vcStatistics(dt);
vbStatistics(dt);
pulStatistics(dt);
icStatistics(dt);
rhcStatistics(dt);
dtrStatistics(dt); MotorLoadStatistics(dt);
TimeStatistics(dt);
Container.Info("[HourStatisticsWork]Hour Statistics");
}
catch (Exception ex)
{
Container.Error($"[HourStatisticsWork]{ex.Message}");
} }

相关配置项

  [DisplayName("运行参数设置")]
[XmlConfigFile(@"Config\WorkSetting.config", )]
public class WorkSetting : XmlConfig<WorkSetting>
{
//private String _LastTool;
///// <summary>最后一个使用的工具</summary>
//[DisplayName("最后一个使用的工具")]
//public String LastTool { get { return _LastTool; } set { _LastTool = value; } } protected override void OnNew()
{
SystemName = "物联网监控系统";
LastUpdateTime = new DateTime(, , ); RabbitMqResolveEnable = true;
RabbitMqResolveInterval = ;//默认1s
HourStatisticsEnable = true;
HourStatisticsInterval = *;//默认30min DayStatisticsEnable = true;
DayStatisticsInterval = * *;//默认12个小时 EnableViewServiceLog = false;
} #region 队列解析 [Description("启用队列解析")]
public bool RabbitMqResolveEnable { get; set; }
[Description("队列解析间隔时间,单位:秒")]
public int RabbitMqResolveInterval { get; set; } #endregion #region 小时统计 [Description("启用小时统计")]
public bool HourStatisticsEnable { get; set; }
[Description("小时统计间隔时间,单位:秒")]
public int HourStatisticsInterval { get; set; }
#endregion #region 自然日统计 [Description("启用自然日统计")]
public bool DayStatisticsEnable { get; set; }
[Description("自然日统计间隔时间,单位:秒")]
public int DayStatisticsInterval { get; set; }
#endregion #region 异常通知 [Description("启用异常通知")]
public bool ExceptionNotifyEnable { get; set; } [Description("异常通知级别")]
public int ExceptionNotifyLevel { get; set; } #endregion 异常通知 #region 系统 /// <summary>
/// 系统名称
/// </summary>
[Description("系统名称")]
public String SystemName { get; set; } /// <summary>最后更新时间</summary>
[Description("最后更新时间")]
public DateTime LastUpdateTime { get; set; } #endregion 系统 #region Windows Service /// <summary>服务名</summary>
[Description("服务名")]
public String ServiceName { get; set; } /// <summary>显示名</summary>
[Description("显示名")]
public String DisplayName { get; set; } /// <summary>服务描述</summary>
[Description("服务描述")]
public String Description { get; set; } /// <summary>查看服务运行日志</summary>
[Description("查看服务运行日志")]
public bool EnableViewServiceLog { get; set; } #endregion Windows Service
}

一切准备好后,开始生成项目并运行,效果如下:

新生命组件XAgent使用心得

3.发现问题

看起来一切运行正常,但是等到我讲xml文件中的HourStatisticsEnable设置成false时,发现只有第一个队列解析的服务在运行。第三个自然日统计的服务没有运行。这时我注意到,原来是插件运行的先后顺序影响的,即Sort属性。本质上还是JobInterval控制了改插件是否运行。可能XAgent的源代码有些小问题,我没有继续深入到源代码中去查找解决,而是直接通过xml配置文件的Enable判断该组件是否运行。

代码如下:

   public HourStatisticsWork()
{ if (WorkSetting.Current.HourStatisticsEnable)
{
DisplayName = "小时统计组件";
Sort = ;
JobInterval = WorkSetting.Current.HourStatisticsInterval;
}
else
{
//JobInterval = -1; //禁用此组件
}
} public override bool Work()
{
if (WorkSetting.Current.HourStatisticsEnable)
{
StartWork();
}
return base.Work();
}
public override bool Stop()
{
if (_HourTimer != null)
{
_HourTimer.Dispose();
}
return base.Stop();
}
public void StartWork()
{//todo}

另外,该IJob接口借鉴了我曾经的领导的想法。

供大家学习,如有不正不妥之处请大家指正。谢谢!

需要源码的或者帮助的联系我QQ:694666781

新生命组件XAgent使用心得的更多相关文章

  1. windows服务插件利器-新生命组件XAgent使用心得

    1.简单介绍 XAgent为大石头带领下的新生命团队自己开发的一个.Net下的常用的Windows服务管理组件利器,通过在控制台中简单的输入1,2,3,4,5等数字可以实现一步安装.卸载Windows ...

  2. 多文件上传组件FineUploader使用心得

    原文 多文件上传组件FineUploader使用心得 做Web开发的童鞋都知道,需要经常从客户端上传文件到服务端,当然,你可以使用<input type="file"/&gt ...

  3. 关于vue项目中使用组件的一些心得

    在编写一个可能是共组件的情况下,尽量在组件内部只处理相关组件内部的逻辑,组件外的逻辑通过事件总线emit,否则一旦当前组件涉及其他组件的逻辑就会发生耦合,在一个新的组件里面使用的时候,就会造成后悔的情 ...

  4. 新生命Redis组件(&period;Net Core 开源)

    NewLife.Redis 是一个Redis客户端组件,以高性能处理大数据实时计算为目标.Redis协议基础实现Redis/RedisClient位于X组件,本库为扩展实现,主要增加列表结构.哈希结构 ...

  5. react 生命周期函数的一些心得体会

    一.理论 组件本质上是状态机,输入确定,输出一定确定 生命周期的三个阶段,三者时间是不固定的,只是在逻辑上的分类: 二.初始化阶段: getDefaultProps:获取实例的默认属性(即使没有生成实 ...

  6. react 16&period;3&plus; 新生命周期 作业

    1.有哪些⽣命周期被舍弃(3个),哪些⽣命 周期是新增(2个)? componentWillMount().componentWillReceiveProps().componentWillUpdat ...

  7. react 16&period;3&plus; 新生命周期

    react 16.3版本出现了两个新的生命周期函数,并将逐渐废弃componentWillMount().componentWillReceiveProps().componentWillUpdate ...

  8. React-Native新列表组件FlatList和SectionList学习 &vert; &vert; 联动列表实现

    React-Native在0.43推出了两款新的列表组件:FlatList(高性能的简单列表组件)和SectionList(高性能的分组列表组件). 从官方上它们都支持常用的以下功能: 完全跨平台. ...

  9. 新生命团队netcore服务器免费开放计划

    为了便于大家学习测试netcore,我们计划提供1~3台公网Linux服务器(CentOS/Ubuntu),1vCPU+1G内存+100Mbps,为期1年,每周重置系统修改一次密码.对使用者要求如下: ...

随机推荐

  1. hbase集群在启动的时候找不到JAVA&lowbar;HOME的问题

    hbase集群在启动的时候找不到JAVA_HOME的问题,启动集群的时候报错信息如下: root@master:/usr/local/hbase-/bin# ./start-hbase.sh star ...

  2. &num;291 div&period;2

    A.水题 数字翻转,将每一位大于等于5的数字t翻转成9-t,注意不要有前导0,且翻转后数字的位数不变(即9999->9000...刚开始以为应该翻转成0了= =) #include<ios ...

  3. 二:java语法基础:

    1,关键字:其实就是某种语言赋予了特殊含义的单词. 保留字:其实就是还没有赋予特殊含义,但是准备日后要使用过的单词. 2,标示符:其实就是在程序中自定义的名词.比如类名,变量名,函数名.包含 0-9. ...

  4. 转:Eclipse Kepler已支持Java 8

    文章来自于:http://www.infoq.com/cn/news/2014/04/eclipse-kepler-support-java8 期待已久的Java 8已于2014年3月19日正式发布, ...

  5. HTML5新增的一些属性和功能之八——web Worker

    Web Workers 为什么用web workers? 浏览器的原理中决定了页面打开只有一个主线程--UI渲染线程,如果线程中有耗时的程序(js)会阻塞线程,使得页面中其他的UI无法渲染,我们一般把 ...

  6. wince平台下使用log4net记录日志

    前面我写过一篇文章是来介绍windows平台下开发软件使用log4net来记录日志的,详情请参考:用一个简单的示例说明日志记录组件log4net的使用. 我们在wince平台下开发程序也一样需要日志文 ...

  7. &lbrack;置顶&rsqb; 初识window&period;location&period;search

    window.location.search是从当前URL的?号开始的字符串 如:http://www.domain.com/item?id=0064014 它的search就是?id=0064014

  8. Spark第一个研究笔记1一片 - Spark一个简短的引论

    该公司推出的在线项目Spark拥有近1随着时间的推移.有效,Spark事实上,优秀的分布式计算平台,以提高生产力. 开始本篇笔记.此前的研究会Spark研究报告共享出来(由于篇幅的限制,它将被划分成制 ...

  9. java&period;sql&period;SQLException之数组越界

    java.sql.SQLException之数组越界 1.具体错误如下: (1)java.sql.SQLException:Parameter index out of range(0<1) ( ...

  10. jqGrid 手册 - 搜索

    搜索 类型: colModel Options Toolbar Searching Custom Searching Single field searching Advanced Searching ...