lixiaojun
2024-04-04 0dd540621753ff44fca56a253b681780100d8e4e
新增标准化设备、工位运行分析服务
已修改2个文件
已添加21个文件
1305 ■■■■■ 文件已修改
Yw.Run.Core.sln 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/00-core/ConfigHelper.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/00-core/IJobHelper.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/00-core/JobHelper.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/01-equipment/01-service/EquipmentRunAnalyServiceJob.cs 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/01-equipment/01-service/EquipmentRunAnalyServiceJobHelper.cs 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/01-equipment/02-single/EquipmentRunAnalyChangeTimesHelper.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/01-equipment/02-single/EquipmentRunAnalySingleJob.cs 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/01-equipment/02-single/EquipmentRunAnalySingleJobHelper.cs 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/01-equipment/02-single/EquipmentRunAnalySingleJobNameHelper.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/02-emws/01-service/EMWSRunAnalyServiceJob.cs 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/02-emws/01-service/EMWSRunAnalyServiceJobHelper.cs 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/02-emws/02-single/EMWSRunAnalyChangeTimesHelper.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/02-emws/02-single/EMWSRunAnalySingleJob.cs 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/02-emws/02-single/EMWSRunAnalySingleJobHelper.cs 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/02-emws/02-single/EMWSRunAnalySingleJobNameHelper.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/GlobalUsings.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/Program.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Server.Run/Yw.Server.Run.csproj 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Service.Run.Core/Yw.Service.Run.Core.csproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.TopShelf.Run/Program.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.TopShelf.Run/Service.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.TopShelf.Run/Yw.TopShelf.Run.csproj 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Yw.Run.Core.sln
@@ -11,7 +11,11 @@
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yw.Entry.Run.Core", "Yw.Entry.Run.Core\Yw.Entry.Run.Core.csproj", "{B5BCA833-E9A4-46B8-B7CF-40D1EF66B989}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yw.Dto.Run.Core", "Yw.Dto.Run.Core\Yw.Dto.Run.Core.csproj", "{E953B3D9-5F8A-4119-B519-B9A87EAA55A9}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yw.Dto.Run.Core", "Yw.Dto.Run.Core\Yw.Dto.Run.Core.csproj", "{E953B3D9-5F8A-4119-B519-B9A87EAA55A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yw.Server.Run", "Yw.Server.Run\Yw.Server.Run.csproj", "{15CD7CB4-980B-4F7B-87D0-7664AAB530F6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yw.TopShelf.Run", "Yw.TopShelf.Run\Yw.TopShelf.Run.csproj", "{3944FCF7-C6F3-4F6C-AD3D-25AB6FB5BD7F}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -39,6 +43,14 @@
        {E953B3D9-5F8A-4119-B519-B9A87EAA55A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {E953B3D9-5F8A-4119-B519-B9A87EAA55A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {E953B3D9-5F8A-4119-B519-B9A87EAA55A9}.Release|Any CPU.Build.0 = Release|Any CPU
        {15CD7CB4-980B-4F7B-87D0-7664AAB530F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {15CD7CB4-980B-4F7B-87D0-7664AAB530F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {15CD7CB4-980B-4F7B-87D0-7664AAB530F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {15CD7CB4-980B-4F7B-87D0-7664AAB530F6}.Release|Any CPU.Build.0 = Release|Any CPU
        {3944FCF7-C6F3-4F6C-AD3D-25AB6FB5BD7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {3944FCF7-C6F3-4F6C-AD3D-25AB6FB5BD7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {3944FCF7-C6F3-4F6C-AD3D-25AB6FB5BD7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {3944FCF7-C6F3-4F6C-AD3D-25AB6FB5BD7F}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
Yw.Server.Run/00-core/ConfigHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
namespace Yw.Server
{
    /// <summary>
    ///
    /// </summary>
    internal class ConfigHelper
    {
        /// <summary>
        /// é‡ç½®é¢‘率
        /// </summary>
        public static int ResetFrequency
        {
            get
            {
                return Settings.RunParasHelper.Run.Task.Frequency;
            }
        }
    }
}
Yw.Server.Run/00-core/IJobHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
namespace Yw.Server
{
    /// <summary>
    /// ä»»åŠ¡è¾…åŠ©ç±»æŽ¥å£
    /// </summary>
    public interface IJobHelper
    {
        /// <summary>
        /// å¼€å§‹ä»»åŠ¡
        /// </summary>
        Task StartJob();
        /// <summary>
        /// å–消任务
        /// </summary>
        Task CancelJob();
    }
}
Yw.Server.Run/00-core/JobHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
namespace Yw.Server
{
    /// <summary>
    ///
    /// </summary>
    public class JobHelper
    {
        private List<IJobHelper> _jobHelpers = new List<IJobHelper>()
        {
            new EquipmentRunAnalyServiceJobHelper(),
            new EMWSRunAnalyServiceJobHelper()
        };
        /// <summary>
        ///
        /// </summary>
        public void StartJob()
        {
            _jobHelpers.ForEach(async x => await x.StartJob());
        }
        /// <summary>
        ///
        /// </summary>
        public void CancelJob()
        {
            _jobHelpers.ForEach(async x => await x.CancelJob());
        }
    }
}
Yw.Server.Run/01-equipment/01-service/EquipmentRunAnalyServiceJob.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
namespace Yw.Server
{
    /// <summary>
    /// è®¾å¤‡è¿è¡Œåˆ†æžæœåŠ¡ä»»åŠ¡
    /// </summary>
    [DisallowConcurrentExecution]
    public class EquipmentRunAnalyServiceJob : IJob
    {
        private static readonly List<EquipmentRunAnalySingleJobHelper> _jobHelpers = new List<EquipmentRunAnalySingleJobHelper>();
        /// <summary>
        ///
        /// </summary>
        public Task Execute(IJobExecutionContext context)
        {
            return Task.Run(async () =>
           {
               try
               {
                   #region åŠ è½½é…ç½®
                   var configureList = new Yw.Service.RunAnalyConfigure().GetAll();
                   configureList = configureList?.Where(x => x.ObjectType == Yw.Assets.DataType.Equipment).ToList();
                   if (configureList == null || configureList.Count < 1)
                   {
                       LogHelper.Error("设备运行分析服务任务中,未检索到配置信息");
                       CancelJobs();
                       return;
                   }
                   #endregion
                   #region å¼€å¯ä»»åŠ¡
                   foreach (var configure in configureList)
                   {
                       var jobHelper = _jobHelpers.Find(x => x.Configure.ObjectType == configure.ObjectType
                           && x.Configure.ObjectID == configure.ObjectID
                           && x.Configure.ChangeTimes == configure.ChangeTimes
                           && x.Configure.Frequency == configure.Frequency);
                       if (jobHelper == null)
                       {
                           jobHelper = new EquipmentRunAnalySingleJobHelper();
                           await jobHelper.StartJob(configure);
                           _jobHelpers.Add(jobHelper);
                           LogHelper.Info($"设备运行分析服务任务中,数据id:{configure.ObjectID},改变次数:{configure.ChangeTimes},分析频率:{configure.Frequency},计划任务开启!");
                       }
                   }
                   #endregion
                   #region å…³é—­ä»»åŠ¡
                   foreach (var jobHelper in _jobHelpers.ToList())
                   {
                       var configure = configureList.Find(x => x.ObjectType == jobHelper.Configure.ObjectType
                           && x.ObjectID == jobHelper.Configure.ObjectID
                           && x.ChangeTimes == jobHelper.Configure.ChangeTimes
                           && x.Frequency == jobHelper.Configure.Frequency);
                       if (configure == null)
                       {
                           await jobHelper.CancelJob();
                           _jobHelpers.Remove(jobHelper);
                           LogHelper.Info($"设备运行分析服务任务中,,数据id:{jobHelper.Configure.ObjectID},改变次数:{jobHelper.Configure.ChangeTimes},分析频率:{jobHelper.Configure.Frequency},计划任务关闭!");
                       }
                   }
                   #endregion
                   LogHelper.Info($"设备运行分析服务任务中,开启任务数量为{_jobHelpers.Count}!");
               }
               catch (Exception ex)
               {
                   LogHelper.Error("设备运行分析服务任务中,执行出错!", ex);
                   var e = new JobExecutionException(ex);
                   throw e;
               }
           });
        }
        /// <summary>
        /// å–消任务
        /// </summary>
        public static void CancelJobs()
        {
            if (_jobHelpers != null && _jobHelpers.Count > 0)
            {
                _jobHelpers.ForEach(async x => await x.CancelJob());
                _jobHelpers.Clear();
            }
        }
    }
}
Yw.Server.Run/01-equipment/01-service/EquipmentRunAnalyServiceJobHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
namespace Yw.Server
{
    /// <summary>
    /// è®¾å¤‡è¿è¡ŒæœåŠ¡ä»»åŠ¡è¾…åŠ©ç±»
    /// </summary>
    public class EquipmentRunAnalyServiceJobHelper : IJobHelper
    {
        private const string _jobName = "EquipmentRunAnalyServiceJobName";
        private const string _jobGroup = "EquipmentRunAnalyServiceJobGroup";
        private const string _triggerName = "EquipmentRunAnalyServiceJobTrigger";
        private static IScheduler _sched;//调度器
        /// <summary>
        /// å¼€å§‹ä»»åŠ¡
        /// </summary>
        public async Task StartJob()
        {
            if (_sched != null)
                return;
            // 1.创建scheduler的引用
            var fac = new Quartz.Impl.StdSchedulerFactory();
            _sched = await fac.GetScheduler();
            //2.启动 scheduler
            await _sched.Start();
            //3.创建任务
            var job = JobBuilder.Create<EquipmentRunAnalyServiceJob>()
             .WithIdentity(_jobName, _jobGroup)
             .Build();
            //4.创建Trigger
            var trigger = TriggerBuilder.Create()
            .WithIdentity(_triggerName, _jobGroup)
            .WithSimpleSchedule(x => x.WithIntervalInMinutes(ConfigHelper.ResetFrequency)
            .RepeatForever()
            .WithMisfireHandlingInstructionNextWithRemainingCount())
            .Build();
            //5.加入调度管理器
            await _sched.ScheduleJob(job, trigger);
        }
        /// <summary>
        /// å–消任务
        /// </summary>
        public async Task CancelJob()
        {
            if (_sched == null)
                return;
            var triggerKey = new TriggerKey(_triggerName, _jobGroup);
            if (await _sched.CheckExists(triggerKey))
            {
                await _sched.UnscheduleJob(triggerKey);
            }
            EquipmentRunAnalyServiceJob.CancelJobs();
        }
    }
}
Yw.Server.Run/01-equipment/02-single/EquipmentRunAnalyChangeTimesHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
namespace Yw.Server
{
    /// <summary>
    ///
    /// </summary>
    public class EquipmentRunAnalyChangeTimesHelper
    {
        private static ConcurrentDictionary<long, List<Yw.Model.MonitorRealRecord>> _dict = new();//缓存
        /// <summary>
        /// è®¾ç½®
        /// </summary>
        public static void Set(long configureId, int changeTimes, Yw.Model.MonitorRealRecord record)
        {
            _dict.TryAdd(configureId, new List<Yw.Model.MonitorRealRecord>());
            if (_dict[configureId].Count >= changeTimes)
            {
                _dict[configureId].RemoveAt(0);
            }
            if (record != null)
            {
                _dict[configureId].Add(record);
            }
        }
        /// <summary>
        /// æ˜¯å¦æ”¹å˜
        /// </summary>
        public static bool HasChanged(long configureId, int changeTimes)
        {
            if (!_dict.ContainsKey(configureId))
            {
                return false;
            }
            if (_dict[configureId].Count < changeTimes)
            {
                return false;
            }
            if (_dict[configureId].Select(x => x.DataValue).Distinct().Count() > 1)
            {
                return false;
            }
            return true;
        }
    }
}
Yw.Server.Run/01-equipment/02-single/EquipmentRunAnalySingleJob.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,211 @@
namespace Yw.Server
{
    /// <summary>
    /// è®¾å¤‡è¿è¡Œåˆ†æžå•任务
    /// </summary>
    [DisallowConcurrentExecution]//此特性标识 å¿…须等待这次任务执行完成后,才能执行下次任务
    public class EquipmentRunAnalySingleJob : IJob
    {
        internal const string Instance = "Instance";
        private Yw.Model.RunAnalyConfigure _configure;
        /// <summary>
        ///
        /// </summary>
        public Task Execute(IJobExecutionContext context)
        {
            return Task.Run(() =>
            {
                try
                {
                    #region ä»»åŠ¡æ•°æ®
                    var dataMap = context.MergedJobDataMap;
                    var jobModel = (Yw.Model.RunAnalyConfigure)dataMap[Instance];
                    if (jobModel == null)
                    {
                        LogHelper.Info($"设备运行分析单任务中,任务数据传输失败!");
                        return;
                    }
                    var configure = jobModel;
                    _configure = configure;
                    #endregion
                    #region èŽ·å–è®¾å¤‡
                    var allEquipmentList = new Yw.Service.Equipment().GetChildAndSelfByID(configure.ObjectID);
                    if (allEquipmentList == null || allEquipmentList.Count < 1)
                    {
                        LogHelper.Info($"设备运行分析单任务中,设备id:{configure.ObjectID} æ£€ç´¢è®¾å¤‡å¤±è´¥ï¼");
                        return;
                    }
                    var allEquipmentIds = allEquipmentList.Select(x => x.ID).Distinct().ToList();
                    #endregion
                    #region èŽ·å–æµ‹ç‚¹
                    var allMonitorMappingList = new Yw.Service.EquipmentMonitorMapping().GetByEquipmentIds(allEquipmentIds);
                    if (allMonitorMappingList == null || allMonitorMappingList.Count < 1)
                    {
                        LogHelper.Info($"设备运行分析单任务中,设备id:{configure.ObjectID} æ£€ç´¢æµ‹ç‚¹å…³è”失败!");
                        return;
                    }
                    var allMonitorIds = allMonitorMappingList.Select(x => x.MonitorPointID).Distinct().ToList();
                    var allMonitorList = new Yw.Service.MonitorPoint().GetExSignalWithSignalTypeByIds(allMonitorIds);
                    allMonitorList = allMonitorList?.Where(x => x.UseStatus == Yw.Model.eUseStatus.Enable).ToList();
                    if (allMonitorList == null || allMonitorList.Count < 1)
                    {
                        LogHelper.Info($"设备运行分析单任务中,设备id:{configure.ObjectID} æ£€ç´¢æµ‹ç‚¹å¤±è´¥ï¼");
                        return;
                    }
                    #endregion
                    #region è¿è¡Œæµ‹ç‚¹
                    var monitorList = allMonitorList.Where(x => x.SignalList.Exists(t => t.SignalType.Code == Yw.Monitor.SignalType.运行状态)).ToList();
                    if (monitorList == null || monitorList.Count < 1)
                    {
                        LogHelper.Info($"设备运行分析单任务中,设备id:{configure.ObjectID} æ£€ç´¢è¿è¡ŒçŠ¶æ€æµ‹ç‚¹å¤±è´¥ï¼");
                        return;
                    }
                    var monitor = monitorList.Find(x => x.Flags.Contains(Yw.Monitor.Flags.默认));
                    if (monitor == null)
                    {
                        monitor = monitorList.First();
                    }
                    #endregion
                    #region è¿žç»­ç¼“å­˜
                    var lastRecord = new Yw.Service.MonitorRealRecord().GetLastRecord(monitor.SignalList.First().ID);
                    EquipmentRunAnalyChangeTimesHelper.Set(configure.ID, configure.ChangeTimes, lastRecord);
                    #endregion
                    #region æ•°æ®åˆ†æž
                    var run_record = new Yw.Model.RunRealRecord()
                    {
                        ObjectType = configure.ObjectType,
                        ObjectID = configure.ObjectID,
                        DataTime = DateTime.Now,
                        RSa = Yw.Run.RunStatus.Stop,
                        ContinueRunTime = 0,
                        TotalRunTime = 0,
                        BootTimes = 0,
                        AnalyStatus = Yw.Run.AnalyStatus.Normal,
                        AnalyInfo = null
                    };
                    var lastRunRecord = new Yw.Service.RunRealRecord().GetLastRecord(configure.ObjectType, configure.ObjectID);
                    if (lastRunRecord == null)
                    {
                        run_record.AnalyInfo = "首次分析";
                        if (lastRecord == null)
                        {
                            run_record.AnalyStatus = Yw.Run.AnalyStatus.Missing;
                        }
                        else
                        {
                            if (double.TryParse(lastRecord.DataValue, out double outDataValue))
                            {
                                if (outDataValue > 0)
                                {
                                    run_record.RSa = Yw.Run.RunStatus.Run;
                                    run_record.ContinueRunTime += configure.Frequency;
                                    run_record.TotalRunTime += configure.Frequency;
                                    run_record.BootTimes += 1;
                                }
                            }
                            else
                            {
                                run_record.AnalyStatus = Yw.Run.AnalyStatus.Abnormal;
                            }
                        }
                    }
                    else
                    {
                        run_record.RSa = lastRunRecord.RSa;
                        run_record.ContinueRunTime = lastRunRecord.ContinueRunTime;
                        run_record.TotalRunTime = lastRunRecord.TotalRunTime;
                        run_record.BootTimes = lastRunRecord.BootTimes;
                        if (lastRecord == null)
                        {
                            run_record.AnalyStatus = Yw.Run.AnalyStatus.Missing;
                        }
                        else
                        {
                            if (double.TryParse(lastRecord.DataValue, out double outDataValue))
                            {
                                var run_status = outDataValue > 0 ? Yw.Run.RunStatus.Run : Yw.Run.RunStatus.Stop;
                                if (run_status != run_record.RSa)
                                {
                                    if (EquipmentRunAnalyChangeTimesHelper.HasChanged(configure.ID, configure.ChangeTimes))
                                    {
                                        run_record.RSa = run_status;
                                        if (run_status == Yw.Run.RunStatus.Run)
                                        {
                                            run_record.BootTimes += 1;
                                        }
                                        if (run_record.RSa == Yw.Run.RunStatus.Stop)
                                        {
                                            run_record.ContinueRunTime = 0;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                run_record.AnalyStatus = Yw.Run.AnalyStatus.Abnormal;
                            }
                        }
                        if (run_record.RSa == Yw.Run.RunStatus.Run)
                        {
                            run_record.TotalRunTime += configure.Frequency;
                            run_record.ContinueRunTime += configure.Frequency;
                        }
                    }
                    #endregion
                    #region æ•°æ®å­˜å‚¨
                    var bol = new Yw.Service.RunRealRecord().InsertLastRecord(run_record);
                    if (bol)
                    {
                        LogHelper.Info($"设备运行分析单任务中,设备id:{configure.ObjectID} è¿è¡Œè®°å½•分析成功!");
                    }
                    else
                    {
                        LogHelper.Info($"设备运行分析单任务中,设备id:{configure.ObjectID} è¿è¡Œè®°å½•保存失败!");
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"设备运行分析单任务中, æ•°æ®id:{_configure.ObjectID}, æ‰§è¡Œå‡ºé”™", ex);
                    var e = new JobExecutionException(ex);
                    throw e;
                }
            });
        }
    }
}
Yw.Server.Run/01-equipment/02-single/EquipmentRunAnalySingleJobHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
namespace Yw.Server
{
    /// <summary>
    /// è®¾å¤‡è¿è¡Œåˆ†æžå•任务辅助类
    /// </summary>
    public class EquipmentRunAnalySingleJobHelper
    {
        private IScheduler _sched;//调度器
        /// <summary>
        /// é…ç½®
        /// </summary>
        public Yw.Model.RunAnalyConfigure Configure { get; set; }
        /// <summary>
        /// å¼€å§‹ä»»åŠ¡
        /// </summary>
        public async Task StartJob(Yw.Model.RunAnalyConfigure configure)
        {
            if (_sched != null)
            {
                return;
            }
            this.Configure = configure;
            var jobName = EquipmentRunAnalySingleJobNameHelper.GetJobName(configure);
            var jobGroupName = EquipmentRunAnalySingleJobNameHelper.GetJobGroupName(configure);
            var triggerName = EquipmentRunAnalySingleJobNameHelper.GetTriggerName(configure);
            // 1.创建scheduler的引用
            var fac = new Quartz.Impl.StdSchedulerFactory();
            _sched = await fac.GetScheduler();
            //2.启动 scheduler
            await _sched.Start();
            //3.创建任务
            var job = JobBuilder.Create<EquipmentRunAnalySingleJob>()
             .WithIdentity(jobName, jobGroupName)
             .Build();
            job.JobDataMap.Put(EquipmentRunAnalySingleJob.Instance, configure);
            //4.创建Trigger
            var trigger = TriggerBuilder.Create()
               .WithIdentity(triggerName, jobGroupName)
               .WithSimpleSchedule(x => x.WithIntervalInSeconds(configure.Frequency)
               .RepeatForever().WithMisfireHandlingInstructionNextWithRemainingCount())
               .Build();
            //5.加入调度管理器
            await _sched.ScheduleJob(job, trigger);
        }
        /// <summary>
        /// å–消任务
        /// </summary>
        public async Task CancelJob()
        {
            if (_sched == null)
                return;
            var jobGroupName = EquipmentRunAnalySingleJobNameHelper.GetJobGroupName(this.Configure);
            var triggerName = EquipmentRunAnalySingleJobNameHelper.GetTriggerName(this.Configure);
            var triggerKey = new TriggerKey(triggerName, jobGroupName);
            if (await _sched.CheckExists(triggerKey))
            {
                await _sched.UnscheduleJob(triggerKey);
            }
        }
    }
}
Yw.Server.Run/01-equipment/02-single/EquipmentRunAnalySingleJobNameHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
namespace Yw.Server
{
    /// <summary>
    /// è®¾å¤‡è¿è¡Œå•任务名称辅助类
    /// </summary>
    public class EquipmentRunAnalySingleJobNameHelper
    {
        private const string _jobNameHeader = "EquipmentRunAnalySingleJobName";
        private const string _jobGroupHeader = "EquipmentRunAnalySingleJobGroup";
        private const string _triggerNameHeader = "EquipmentRunAnalySingleJobTrigger";
        /// <summary>
        /// èŽ·å–ä»»åŠ¡åç§°
        /// </summary>
        public static string GetJobName(Yw.Model.RunAnalyConfigure rhs)
        {
            return $"{_jobNameHeader}_{rhs.ID}";
        }
        /// <summary>
        /// èŽ·å–ä»»åŠ¡ç»„åç§°
        /// </summary>
        public static string GetJobGroupName(Yw.Model.RunAnalyConfigure rhs)
        {
            return $"{_jobGroupHeader}_{rhs.ID}";
        }
        /// <summary>
        /// èŽ·å–è§¦å‘å™¨åç§°
        /// </summary>
        public static string GetTriggerName(Yw.Model.RunAnalyConfigure rhs)
        {
            return $"{_triggerNameHeader}_{rhs.ID}";
        }
    }
}
Yw.Server.Run/02-emws/01-service/EMWSRunAnalyServiceJob.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
namespace Yw.Server
{
    /// <summary>
    /// å·¥ä½è¿è¡Œåˆ†æžæœåŠ¡ä»»åŠ¡
    /// </summary>
    [DisallowConcurrentExecution]
    public class EMWSRunAnalyServiceJob : IJob
    {
        private static readonly List<EMWSRunAnalySingleJobHelper> _jobHelpers = new List<EMWSRunAnalySingleJobHelper>();
        /// <summary>
        ///
        /// </summary>
        public Task Execute(IJobExecutionContext context)
        {
            return Task.Run(async () =>
           {
               try
               {
                   #region åŠ è½½é…ç½®
                   var configureList = new Yw.Service.RunAnalyConfigure().GetAll();
                   configureList = configureList?.Where(x => x.ObjectType == Yw.EMWS.DataType.WorkSite).ToList();
                   if (configureList == null || configureList.Count < 1)
                   {
                       LogHelper.Error("工位运行分析服务任务中,未检索到配置信息");
                       CancelJobs();
                       return;
                   }
                   #endregion
                   #region å¼€å¯ä»»åŠ¡
                   foreach (var configure in configureList)
                   {
                       var jobHelper = _jobHelpers.Find(x => x.Configure.ObjectType == configure.ObjectType
                           && x.Configure.ObjectID == configure.ObjectID
                           && x.Configure.ChangeTimes == configure.ChangeTimes
                           && x.Configure.Frequency == configure.Frequency);
                       if (jobHelper == null)
                       {
                           jobHelper = new EMWSRunAnalySingleJobHelper();
                           await jobHelper.StartJob(configure);
                           _jobHelpers.Add(jobHelper);
                           LogHelper.Info($"工位运行分析服务任务中,数据id:{configure.ObjectID},改变次数:{configure.ChangeTimes},分析频率:{configure.Frequency},计划任务开启!");
                       }
                   }
                   #endregion
                   #region å…³é—­ä»»åŠ¡
                   foreach (var jobHelper in _jobHelpers.ToList())
                   {
                       var configure = configureList.Find(x => x.ObjectType == jobHelper.Configure.ObjectType
                           && x.ObjectID == jobHelper.Configure.ObjectID
                           && x.ChangeTimes == jobHelper.Configure.ChangeTimes
                           && x.Frequency == jobHelper.Configure.Frequency);
                       if (configure == null)
                       {
                           await jobHelper.CancelJob();
                           _jobHelpers.Remove(jobHelper);
                           LogHelper.Info($"工位运行分析服务任务中,,数据id:{jobHelper.Configure.ObjectID},改变次数:{jobHelper.Configure.ChangeTimes},分析频率:{jobHelper.Configure.Frequency},计划任务关闭!");
                       }
                   }
                   #endregion
                   LogHelper.Info($"工位运行分析服务任务中,开启任务数量为{_jobHelpers.Count}!");
               }
               catch (Exception ex)
               {
                   LogHelper.Error("工位运行分析服务任务中,执行出错!", ex);
                   var e = new JobExecutionException(ex);
                   throw e;
               }
           });
        }
        /// <summary>
        /// å–消任务
        /// </summary>
        public static void CancelJobs()
        {
            if (_jobHelpers != null && _jobHelpers.Count > 0)
            {
                _jobHelpers.ForEach(async x => await x.CancelJob());
                _jobHelpers.Clear();
            }
        }
    }
}
Yw.Server.Run/02-emws/01-service/EMWSRunAnalyServiceJobHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
namespace Yw.Server
{
    /// <summary>
    /// å·¥ä½è¿è¡ŒæœåŠ¡ä»»åŠ¡è¾…åŠ©ç±»
    /// </summary>
    public class EMWSRunAnalyServiceJobHelper : IJobHelper
    {
        private const string _jobName = "EMWSRunAnalyServiceJobName";
        private const string _jobGroup = "EMWSRunAnalyServiceJobGroup";
        private const string _triggerName = "EMWSRunAnalyServiceJobTrigger";
        private static IScheduler _sched;//调度器
        /// <summary>
        /// å¼€å§‹ä»»åŠ¡
        /// </summary>
        public async Task StartJob()
        {
            if (_sched != null)
                return;
            // 1.创建scheduler的引用
            var fac = new Quartz.Impl.StdSchedulerFactory();
            _sched = await fac.GetScheduler();
            //2.启动 scheduler
            await _sched.Start();
            //3.创建任务
            var job = JobBuilder.Create<EMWSRunAnalyServiceJob>()
             .WithIdentity(_jobName, _jobGroup)
             .Build();
            //4.创建Trigger
            var trigger = TriggerBuilder.Create()
            .WithIdentity(_triggerName, _jobGroup)
            .WithSimpleSchedule(x => x.WithIntervalInMinutes(ConfigHelper.ResetFrequency)
            .RepeatForever()
            .WithMisfireHandlingInstructionNextWithRemainingCount())
            .Build();
            //5.加入调度管理器
            await _sched.ScheduleJob(job, trigger);
        }
        /// <summary>
        /// å–消任务
        /// </summary>
        public async Task CancelJob()
        {
            if (_sched == null)
                return;
            var triggerKey = new TriggerKey(_triggerName, _jobGroup);
            if (await _sched.CheckExists(triggerKey))
            {
                await _sched.UnscheduleJob(triggerKey);
            }
            EMWSRunAnalyServiceJob.CancelJobs();
        }
    }
}
Yw.Server.Run/02-emws/02-single/EMWSRunAnalyChangeTimesHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
namespace Yw.Server
{
    /// <summary>
    ///
    /// </summary>
    public class EMWSRunAnalyChangeTimesHelper
    {
        private static ConcurrentDictionary<long, List<Yw.Model.MonitorRealRecord>> _dict = new();//缓存
        /// <summary>
        /// è®¾ç½®
        /// </summary>
        public static void Set(long configureId, int changeTimes, Yw.Model.MonitorRealRecord record)
        {
            _dict.TryAdd(configureId, new List<Yw.Model.MonitorRealRecord>());
            if (_dict[configureId].Count >= changeTimes)
            {
                _dict[configureId].RemoveAt(0);
            }
            if (record != null)
            {
                _dict[configureId].Add(record);
            }
        }
        /// <summary>
        /// æ˜¯å¦æ”¹å˜
        /// </summary>
        public static bool HasChanged(long configureId, int changeTimes)
        {
            if (!_dict.ContainsKey(configureId))
            {
                return false;
            }
            if (_dict[configureId].Count < changeTimes)
            {
                return false;
            }
            if (_dict[configureId].Select(x => x.DataValue).Distinct().Count() > 1)
            {
                return false;
            }
            return true;
        }
    }
}
Yw.Server.Run/02-emws/02-single/EMWSRunAnalySingleJob.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,222 @@
namespace Yw.Server
{
    /// <summary>
    /// å·¥ä½è¿è¡Œåˆ†æžå•任务
    /// </summary>
    [DisallowConcurrentExecution]//此特性标识 å¿…须等待这次任务执行完成后,才能执行下次任务
    public class EMWSRunAnalySingleJob : IJob
    {
        internal const string Instance = "Instance";
        private Yw.Model.RunAnalyConfigure _configure;
        /// <summary>
        ///
        /// </summary>
        public Task Execute(IJobExecutionContext context)
        {
            return Task.Run(() =>
            {
                try
                {
                    #region ä»»åŠ¡æ•°æ®
                    var dataMap = context.MergedJobDataMap;
                    var jobModel = (Yw.Model.RunAnalyConfigure)dataMap[Instance];
                    if (jobModel == null)
                    {
                        LogHelper.Info($"工位运行分析单任务中,任务数据传输失败!");
                        return;
                    }
                    var configure = jobModel;
                    _configure = configure;
                    #endregion
                    #region æœåС准备
                    var service_work_site = new Lazy<Yw.Service.EMWSWorkSite>(() => new Yw.Service.EMWSWorkSite());//工位服务
                    var service_work_mapping = new Lazy<Yw.Service.EMWSWorkMapping>(() => new Yw.Service.EMWSWorkMapping());//工位与测点映射服务
                    var service_monitor = new Lazy<Yw.Service.MonitorPoint>(() => new Yw.Service.MonitorPoint());//测点服务
                    var service_monitor_record = new Lazy<Yw.Service.MonitorRealRecord>(() => new Yw.Service.MonitorRealRecord());//测点记录服务
                    var service_run_record = new Lazy<Yw.Service.RunRealRecord>(() => new Yw.Service.RunRealRecord());//运行分析记录服务
                    #endregion
                    #region èŽ·å–å·¥ä½
                    var allWorKSiteList = service_work_site.Value.GetChildAndSelfByID(configure.ObjectID);
                    if (allWorKSiteList == null || allWorKSiteList.Count < 1)
                    {
                        LogHelper.Info($"工位运行分析单任务中,获取工位数据失败!");
                        return;
                    }
                    var allWorkSiteIds = allWorKSiteList.Select(x => x.ID).Distinct().ToList();
                    var currentWorkSite = allWorKSiteList.Find(x => x.ID == configure.ObjectID);
                    #endregion
                    #region èŽ·å–æµ‹ç‚¹
                    var allMonitorMappingList = service_work_mapping.Value.GetByWorkIdsAndMappingType(allWorkSiteIds, Yw.Monitor.DataType.MonitorPoint);
                    if (allMonitorMappingList == null || allMonitorMappingList.Count < 1)
                    {
                        LogHelper.Info($"工位运行分析单任务中,工位名称:{currentWorkSite.Name},工位id:{currentWorkSite.ID},获取关联测点信息失败!");
                        return;
                    }
                    var allMonitorIds = allMonitorMappingList.Select(x => x.MappingID).Distinct().ToList();
                    var allMonitorList = service_monitor.Value.GetExSignalWithSignalTypeByIds(allMonitorIds);
                    allMonitorList = allMonitorList?.Where(x => x.UseStatus == Yw.Model.eUseStatus.Enable).ToList();
                    allMonitorList = allMonitorList?.Where(x => x.CronType == Yw.Monitor.eCronType.Real).ToList();
                    if (allMonitorList == null || allMonitorList.Count < 1)
                    {
                        LogHelper.Info($"工位运行分析单任务中,工位名称:{currentWorkSite.Name},工位id:{currentWorkSite.ID},获取有效测点信息失败!");
                        return;
                    }
                    #endregion
                    #region è¿è¡Œæµ‹ç‚¹
                    var monitorList = allMonitorList.Where(x => x.SignalList.Exists(t => t.SignalType.Code == Yw.Monitor.SignalType.运行状态)).ToList();
                    if (monitorList == null || monitorList.Count < 1)
                    {
                        LogHelper.Info($"工位运行分析单任务中,设备id:{configure.ObjectID} æ£€ç´¢è¿è¡ŒçŠ¶æ€æµ‹ç‚¹å¤±è´¥ï¼");
                        return;
                    }
                    var monitor = monitorList.Find(x => x.Flags.Contains(Yw.Monitor.Flags.默认));
                    if (monitor == null)
                    {
                        monitor = monitorList.First();
                    }
                    #endregion
                    #region è¿žç»­ç¼“å­˜
                    var lastMonitorRecord = service_monitor_record.Value.GetLastRecord(monitor.SignalList.First().ID);
                    EMWSRunAnalyChangeTimesHelper.Set(configure.ID, configure.ChangeTimes, lastMonitorRecord);
                    #endregion
                    #region æ•°æ®åˆ†æž
                    var run_record = new Yw.Model.RunRealRecord()
                    {
                        ObjectType = configure.ObjectType,
                        ObjectID = configure.ObjectID,
                        DataTime = DateTime.Now,
                        RSa = Yw.Run.RunStatus.Stop,
                        ContinueRunTime = 0,
                        TotalRunTime = 0,
                        BootTimes = 0,
                        AnalyStatus = Yw.Run.AnalyStatus.Normal,
                        AnalyInfo = null
                    };
                    var lastRunRecord = service_run_record.Value.GetLastRecord(configure.ObjectType, configure.ObjectID);
                    if (lastRunRecord == null)
                    {
                        run_record.AnalyInfo = "首次分析";
                        if (lastMonitorRecord == null)
                        {
                            run_record.AnalyStatus = Yw.Run.AnalyStatus.Missing;
                        }
                        else
                        {
                            if (double.TryParse(lastMonitorRecord.DataValue, out double outDataValue))
                            {
                                if (outDataValue > 0)
                                {
                                    run_record.RSa = Yw.Run.RunStatus.Run;
                                    run_record.ContinueRunTime += configure.Frequency;
                                    run_record.TotalRunTime += configure.Frequency;
                                    run_record.BootTimes += 1;
                                }
                            }
                            else
                            {
                                run_record.AnalyStatus = Yw.Run.AnalyStatus.Abnormal;
                            }
                        }
                    }
                    else
                    {
                        run_record.RSa = lastRunRecord.RSa;
                        run_record.ContinueRunTime = lastRunRecord.ContinueRunTime;
                        run_record.TotalRunTime = lastRunRecord.TotalRunTime;
                        run_record.BootTimes = lastRunRecord.BootTimes;
                        if (lastMonitorRecord == null)
                        {
                            run_record.AnalyStatus = Yw.Run.AnalyStatus.Missing;
                        }
                        else
                        {
                            if (double.TryParse(lastMonitorRecord.DataValue, out double outDataValue))
                            {
                                var run_status = outDataValue > 0 ? Yw.Run.RunStatus.Run : Yw.Run.RunStatus.Stop;
                                if (run_status != run_record.RSa)
                                {
                                    if (EMWSRunAnalyChangeTimesHelper.HasChanged(configure.ID, configure.ChangeTimes))
                                    {
                                        run_record.RSa = run_status;
                                        if (run_status == Yw.Run.RunStatus.Run)
                                        {
                                            run_record.BootTimes += 1;
                                        }
                                        if (run_record.RSa == Yw.Run.RunStatus.Stop)
                                        {
                                            run_record.ContinueRunTime = 0;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                run_record.AnalyStatus = Yw.Run.AnalyStatus.Abnormal;
                            }
                        }
                        if (run_record.RSa == Yw.Run.RunStatus.Run)
                        {
                            run_record.TotalRunTime += configure.Frequency;
                            run_record.ContinueRunTime += configure.Frequency;
                        }
                    }
                    #endregion
                    #region æ•°æ®å­˜å‚¨
                    var bol = service_run_record.Value.InsertLastRecord(run_record);
                    if (bol)
                    {
                        LogHelper.Info($"工位运行分析单任务中,工位名称:{currentWorkSite.Name},工位id:{currentWorkSite.ID}, è¿è¡Œè®°å½•分析成功!");
                    }
                    else
                    {
                        LogHelper.Info($"工位运行分析单任务中,工位名称:{currentWorkSite.Name},工位id:{currentWorkSite.ID},运行记录保存失败!");
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"工位运行分析单任务中, å·¥ä½id:{_configure.ObjectID}, æ‰§è¡Œå‡ºé”™", ex);
                    var e = new JobExecutionException(ex);
                    throw e;
                }
            });
        }
    }
}
Yw.Server.Run/02-emws/02-single/EMWSRunAnalySingleJobHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
namespace Yw.Server
{
    /// <summary>
    /// å·¥ä½è¿è¡Œåˆ†æžå•任务辅助类
    /// </summary>
    public class EMWSRunAnalySingleJobHelper
    {
        private IScheduler _sched;//调度器
        /// <summary>
        /// é…ç½®
        /// </summary>
        public Yw.Model.RunAnalyConfigure Configure { get; set; }
        /// <summary>
        /// å¼€å§‹ä»»åŠ¡
        /// </summary>
        public async Task StartJob(Yw.Model.RunAnalyConfigure configure)
        {
            if (_sched != null)
            {
                return;
            }
            this.Configure = configure;
            var jobName = EMWSRunAnalySingleJobNameHelper.GetJobName(configure);
            var jobGroupName = EMWSRunAnalySingleJobNameHelper.GetJobGroupName(configure);
            var triggerName = EMWSRunAnalySingleJobNameHelper.GetTriggerName(configure);
            // 1.创建scheduler的引用
            var fac = new Quartz.Impl.StdSchedulerFactory();
            _sched = await fac.GetScheduler();
            //2.启动 scheduler
            await _sched.Start();
            //3.创建任务
            var job = JobBuilder.Create<EMWSRunAnalySingleJob>()
             .WithIdentity(jobName, jobGroupName)
             .Build();
            job.JobDataMap.Put(EMWSRunAnalySingleJob.Instance, configure);
            //4.创建Trigger
            var trigger = TriggerBuilder.Create()
               .WithIdentity(triggerName, jobGroupName)
               .WithSimpleSchedule(x => x.WithIntervalInSeconds(configure.Frequency)
               .RepeatForever().WithMisfireHandlingInstructionNextWithRemainingCount())
               .Build();
            //5.加入调度管理器
            await _sched.ScheduleJob(job, trigger);
        }
        /// <summary>
        /// å–消任务
        /// </summary>
        public async Task CancelJob()
        {
            if (_sched == null)
                return;
            var jobGroupName = EMWSRunAnalySingleJobNameHelper.GetJobGroupName(this.Configure);
            var triggerName = EMWSRunAnalySingleJobNameHelper.GetTriggerName(this.Configure);
            var triggerKey = new TriggerKey(triggerName, jobGroupName);
            if (await _sched.CheckExists(triggerKey))
            {
                await _sched.UnscheduleJob(triggerKey);
            }
        }
    }
}
Yw.Server.Run/02-emws/02-single/EMWSRunAnalySingleJobNameHelper.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
namespace Yw.Server
{
    /// <summary>
    /// å·¥ä½è¿è¡Œå•任务名称辅助类
    /// </summary>
    public class EMWSRunAnalySingleJobNameHelper
    {
        private const string _jobNameHeader = "EMWSRunAnalySingleJobName";
        private const string _jobGroupHeader = "EMWSRunAnalySingleJobGroup";
        private const string _triggerNameHeader = "EMWSRunAnalySingleJobTrigger";
        /// <summary>
        /// èŽ·å–ä»»åŠ¡åç§°
        /// </summary>
        public static string GetJobName(Yw.Model.RunAnalyConfigure rhs)
        {
            return $"{_jobNameHeader}_{rhs.ID}";
        }
        /// <summary>
        /// èŽ·å–ä»»åŠ¡ç»„åç§°
        /// </summary>
        public static string GetJobGroupName(Yw.Model.RunAnalyConfigure rhs)
        {
            return $"{_jobGroupHeader}_{rhs.ID}";
        }
        /// <summary>
        /// èŽ·å–è§¦å‘å™¨åç§°
        /// </summary>
        public static string GetTriggerName(Yw.Model.RunAnalyConfigure rhs)
        {
            return $"{_triggerNameHeader}_{rhs.ID}";
        }
    }
}
Yw.Server.Run/GlobalUsings.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
global using System.Text;
global using System.ComponentModel;
global using System.Security.Cryptography;
global using System.Reflection;
global using System.Data;
global using System.Globalization;
global using System.Collections;
global using Quartz;
global using Yw;
global using System.Collections.Concurrent;
Yw.Server.Run/Program.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
// See https://aka.ms/new-console-template for more information
using Yw.Server;
LogHelper.Info("开始启动苏州金庭服务...");
var jobHelper = new JobHelper();
jobHelper.StartJob();
AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
{
    jobHelper.CancelJob();
};
LogHelper.Info("苏州金庭服务启动成功!");
Console.ReadLine();
Yw.Server.Run/Yw.Server.Run.csproj
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>disable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Yw.Quartz.Core" Version="3.0.0" />
    <PackageReference Include="Yw.Service.Assets.Core" Version="3.0.5" />
    <PackageReference Include="Yw.Service.EMWS.Core" Version="3.0.1" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\Yw.Service.Run.Core\Yw.Service.Run.Core.csproj" />
  </ItemGroup>
</Project>
Yw.Service.Run.Core/Yw.Service.Run.Core.csproj
@@ -27,8 +27,8 @@
    </ItemGroup>
    <ItemGroup>
      <PackageReference Include="Yw.DAL.PostgreSql.Core" Version="3.0.0" />
      <PackageReference Include="Yw.DAL.SQLite.Core" Version="3.0.0" />
      <PackageReference Include="Yw.DAL.PostgreSql.Core" Version="3.0.1" />
      <PackageReference Include="Yw.DAL.SQLite.Core" Version="3.0.1" />
      <PackageReference Include="Yw.DALFactory.Core" Version="3.0.0" />
      <PackageReference Include="Yw.ExchangeFactory.Core" Version="3.0.0" />
      <PackageReference Include="Yw.LCacheFactory.Core" Version="3.0.0" />
Yw.TopShelf.Run/Program.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
// See https://aka.ms/new-console-template for more information
using Yw.TopShelf;
using Topshelf;
//SZJT
HostFactory.Run(x =>
{
    x.Service<Service>();
    x.RunAsLocalSystem();
    x.SetDescription("智慧泵站Core版运行分析程序(SZJT)");
    x.SetDisplayName("IStation.Core.Server.Run.SZJT");
    x.SetServiceName("IStation.Core.Server.Run.SZJT");
    x.EnableServiceRecovery(r => r.RestartService(TimeSpan.FromSeconds(120)));
    x.StartAutomatically();
});
Yw.TopShelf.Run/Service.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
using Topshelf;
using Yw.Server;
namespace Yw.TopShelf
{
    /// <summary>
    ///
    /// </summary>
    public class Service : ServiceControl
    {
        private readonly JobHelper _jobHelper = new();
        /// <summary>
        ///
        /// </summary>
        /// <param name="hostControl"></param>
        /// <returns></returns>
        public bool Start(HostControl hostControl)
        {
            _jobHelper.StartJob();
            return true;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="hostControl"></param>
        /// <returns></returns>
        public bool Stop(HostControl hostControl)
        {
            _jobHelper.CancelJob();
            return true;
        }
    }
}
Yw.TopShelf.Run/Yw.TopShelf.Run.csproj
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Yw.TopShelf" Version="3.0.0" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\Yw.Server.Run\Yw.Server.Run.csproj" />
  </ItemGroup>
</Project>