Winform开发框架之通用定时服务管理

做项目的时候,或多或少需要和其他外部系统或者接口进行数据交互,有些是单向的获取,有些可能是修改状态后再写回去,不管如何,这个都可以称之为数据同步操作,如人员信息同步、业务数据同步、第三方接口数据同步等等。

数据同步涉及到一个同步时间的问题,一般不敏感的数据,一天或者一周左右同步一次就可以了,有些可能需要间隔更短一点。

同步的逻辑不同,有些可能写数据库就可以了,有些可能需要访问WebService或者其他接口,然后在进行数据获取,保存等操作,回写的时候,也一般是调用WebService这样的接口修改数据。

每个同步实现我们都需要做大量重复性工作,如Windows服务安装、卸载、或者基础性的工作,有没有一种方式可以隔离业务逻辑和常用的东西呢?

1、通用定时服务管理模块设计

这样的同步操作看似没有很多必然的关联性,但是,这些都是很常见的东西,如果以插件架构方式来组织各个不同的业务封装,通过参数配置实现同步间隔不同,核心的同步模块其实是很多类似的东西,而同步一般通过Windows访问进行,这样通用的我们可以把它封装成一个通用的Windows服务。再辅以一个界面管理模块来管理服务的安装、卸载、启动、停止、测试等操作就可以了,整个Window服务的插件设计框架如下所示。

Winform开发框架之通用定时服务管理

Windows定时服务-文件视图如下所示:

Winform开发框架之通用定时服务管理

以上架构,有几个特点,

1、 基于插件结构,扩展容易。

2、 一个定时服务【通用的WIndows服务模块】,可以同时运行很多个不同的定时规则的定时服务应用。

3、 一个通用的服务管理界面【Windows定时服务管理】,来对定时服务的安装、卸载、启动、停止、测试等操作,并且可以对插件进行可视化配置。

4、【通用的WIndows服务模块】提供参数化安装,卸载、测试的功能。

5、【Windows定时服务管理】提供DOS测试和WInform进度测试的集成。

6、 插件参数化配置,提供插件各种参数的配置,统一调度。

6、插件通过反射加载不同的定时服务应用,实现松耦合和强类型接口的转换,确保弹性化和安全性。

7、整个定时服务管理模块,可以在不同的场合下实现重用,每次只是定时服务应用的不同而已。

8、定时时间设置,提供多样化的设置,可以在间隔时间、每天整点运行、每月指定日期时间运行多种方式。

整个定时服务管理通用模块,可以最大化的实现工具重用、逻辑重用,不管业务场景如何变化,基本上不需要调整了,只需要把定时服务应用ABC模块开发好,参数配置好,丢进去就可以了。

2、定时服务控制台【Windows定时服务管理】的界面设计

开发好的【Windows定时服务管理】界面如下所示,运行后,会把XML文档里面的插件加载在下面的列表中,供查看和修改操作。

Winform开发框架之通用定时服务管理

插件的XML配置信息如下所示。

<?xml version="1.0"?>
<ArrayOfPlugInSetting>
  <PlugInSetting>
    <!--插件程序名称-->
    <Name>测试名称</Name>
    <!--插件描述内容-->
    <Description>测试描述</Description>
    <!--运行同步服务的间隔时间(单位:分钟)-->
    <ServiceCycleMinutes>1</ServiceCycleMinutes>
    <!--Windows服务在固定时刻(0~23时刻)运行-->
    <ServiceRunAtHour>23</ServiceRunAtHour>
    <!--Windows服务在每月指定天运行,小时按ServiceRunAtHour的值-->
    <ServiceRunAtDay>1</ServiceRunAtDay>
    <!--运行模式,0为间隔分钟运行  1为固定时刻运行, 2为按月某天和小时  其他值为禁用-->
    <RunMode>0</RunMode>
    <!--插件的类型名称:插件类名,程序集名称-->
    <PlugInTypeName>WHC.PlugInService.ClassName,WHC.PlugInService</PlugInTypeName>
  </PlugInSetting>
</ArrayOfPlugInSetting>

单击安装服务,控制台程序调用DOS命令+参数来实现通用定时WIndows服务的安装。

Winform开发框架之通用定时服务管理

安装后,系统的Windows服务列表中就会增加一个【定时服务】的服务模块了,这样就证明我们顺利安装了通用定时服务了。

Winform开发框架之通用定时服务管理

定时服务控制台的状态也会同时刷新,并且把服务的状态和类型显示在【服务状态】里面,这个时候,可以对服务进行卸载、测试、停止服务、重新启动、刷新状态等相关操作了。

Winform开发框架之通用定时服务管理

如果对于很多定时服务应用,每种需要进行动态的禁用或者设置定时方式,那么可以在列表上右键进行相关的操作。

Winform开发框架之通用定时服务管理

3、定时应用测试及界面集成

在开发过程中,发现经常性的需要调试我们自己的定时应用ABC是否正确生成,可以通过【DOS测试】和【进度测试】这两个按钮进行逻辑测试,这个没有触发Windows的情况下进行调用,可以看到具体的效果如下所示。

Winform开发框架之通用定时服务管理

一般来说,提供以上DOS窗口来进行跟踪调试就可以了,但是有时候,我们想在Winform程序中调用立即同步的操作的时候,可以使用进度测试的逻辑代码进行处理,这样可以在主界面中显示进度。

由于是插件架构,因此在和Winform集成的时候,其实是和这个定时服务控制台一样,我们在我们的Winform程序中,加载应用插件,进行调用就可以了,调用代码如下所示。

        private void btnTestProgress_Click(object sender, EventArgs e)
        {
            try
            {                
                this.lblTips.Visible = true;
                this.progressBar1.Visible = true;

                //Winform进度条指示测试
                foreach (string key in pluginList.Keys)
                {
                    ITimingPlugIn obj = pluginList[key];
                    if (obj != null)
                    {
                        obj.ProgressChanged += new ProgressChangedEventHandler(TimingPlugIn_ProgressChanged);
                        obj.Excute();

                        LogTextHelper.Info(string.Format("插件【{0}】运行一次", key));
                    }
                }

                MessageUtil.ShowTips("操作完成");
            }
            finally
            {
                lblTips.Text = "";
                this.lblTips.Visible = false;
                this.progressBar1.Visible = false;
            }
        }

        void TimingPlugIn_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //ITimingPlugIn obj = sender as ITimingPlugIn;
            progressBar1.Value = e.ProgressPercentage;
            if (e.UserState != null)
            {
                lblTips.Text = e.UserState.ToString();
            }

            Thread.Sleep(100);
            Application.DoEvents();
        }

调用进度测试的界面如下所示,它可以把各种同步详细情况显示在主界面上。

Winform开发框架之通用定时服务管理

对于整个模块的运行操作,我们通过日志进行记录,这样可以详细看到具体的操作了。

Winform开发框架之通用定时服务管理

本文转自博客园伍华聪的博客,原文链接:Winform开发框架之通用定时服务管理,如需转载请自行联系原博主。



 

上一篇:分享一个小设置-项目启动时服务器指向本地IIS


下一篇:超线程处理器使用前:检查系统需求