private void InitializeLocalPerformanceCounters() { _getActiveThreads = () => _smartThreadPool.PerformanceCountersReader.ActiveThreads; _getInUseThreads = () => _smartThreadPool.PerformanceCountersReader.InUseThreads; _getQueuedWorkItems = () => _smartThreadPool.PerformanceCountersReader.WorkItemsQueued; _getCompletedWorkItems = () => _smartThreadPool.PerformanceCountersReader.WorkItemsProcessed; }
private void InitializeLocalPerformanceCounters() { _getActiveThreads = () => Convert.ToInt32(m_SmartThreadPool.PerformanceCountersReader.ActiveThreads); _getInUseThreads = () => Convert.ToInt32(m_SmartThreadPool.PerformanceCountersReader.InUseThreads); _getQueuedWorkItems = () => Convert.ToInt32(m_SmartThreadPool.PerformanceCountersReader.WorkItemsQueued); _getCompletedWorkItems = () => Convert.ToInt32(m_SmartThreadPool.PerformanceCountersReader.WorkItemsProcessed); }
private void InitializeWindowsPerformanceCounters() { this._pcActiveThreads = new System.Diagnostics.PerformanceCounter(); this._pcInUseThreads = new System.Diagnostics.PerformanceCounter(); this._pcQueuedWorkItems = new System.Diagnostics.PerformanceCounter(); this._pcCompletedWorkItems = new System.Diagnostics.PerformanceCounter(); this._pcActiveThreads.CategoryName = "测试线程池"; this._pcActiveThreads.CounterName = "活跃线程"; this._pcActiveThreads.InstanceName = "测试线程池工具"; this._pcInUseThreads.CategoryName = "测试线程池"; this._pcInUseThreads.CounterName = "使用中线程"; this._pcInUseThreads.InstanceName = "测试线程池工具"; this._pcQueuedWorkItems.CategoryName = "测试线程池"; this._pcQueuedWorkItems.CounterName = "队列中线程"; this._pcQueuedWorkItems.InstanceName = "测试线程池工具"; this._pcCompletedWorkItems.CategoryName = "测试线程池"; this._pcCompletedWorkItems.CounterName = "任务完成线程"; this._pcCompletedWorkItems.InstanceName = "测试线程池工具"; _getActiveThreads = () => (long)_pcActiveThreads.NextValue(); _getInUseThreads = () => (long)_pcInUseThreads.NextValue(); _getQueuedWorkItems = () => (long)_pcQueuedWorkItems.NextValue(); _getCompletedWorkItems = () => (long)_pcCompletedWorkItems.NextValue(); }
public void Init(SmartThreadPool _smartThreadPool) { getActiveThreads = () => _smartThreadPool.PerformanceCountersReader.ActiveThreads; getInUseThreads = () => _smartThreadPool.PerformanceCountersReader.InUseThreads; getQueuedWorkItems = () => _smartThreadPool.PerformanceCountersReader.WorkItemsQueued; getCompletedWorkItems = () => _smartThreadPool.PerformanceCountersReader.WorkItemsProcessed; if (statisticsChart != null) { statisticsChart.Legends.Clear(); statisticsChart.Series.Clear(); Legend legend = new Legend(); legend.Docking = Docking.Right; statisticsChart.Legends.Add(legend); Series series = new Series("Data"); series.ChartType = SeriesChartType.Pie; series["PieLabelStyle"] = "Inside"; series["PieLineColor"] = "Black"; series.ChartType = SeriesChartType.Pie; series.LegendText = "#PERCENT"; statisticsChart.Series.Add(series); } if (timeEfficiencyChart != null) { timeEfficiencyChart.Legends.Clear(); timeEfficiencyChart.Series.Clear(); Legend legend = new Legend(); legend.Docking = Docking.Top; timeEfficiencyChart.Legends.Add(legend); Series series1 = new Series(); series1.ChartArea = "LineChart_ChartArea"; series1.Name = "待处理"; series1.ChartType = SeriesChartType.Line; timeEfficiencyChart.Series.Add(series1); Series series2 = new Series(); series2.ChartArea = "LineChart_ChartArea"; series2.Name = "队列中"; series2.ChartType = SeriesChartType.Line; timeEfficiencyChart.Series.Add(series2); Series series3 = new Series(); series3.ChartArea = "LineChart_ChartArea"; series3.Name = "成功"; series3.ChartType = SeriesChartType.Line; timeEfficiencyChart.Series.Add(series3); Series series4 = new Series(); series4.ChartArea = "LineChart_ChartArea"; series4.Name = "取消"; series4.ChartType = SeriesChartType.Line; timeEfficiencyChart.Series.Add(series4); Series series5 = new Series(); series5.ChartArea = "LineChart_ChartArea"; series5.Name = "失败"; series5.ChartType = SeriesChartType.Line; timeEfficiencyChart.Series.Add(series5); } if (usageThreadsInPool != null) { usageThreadsInPool.Maximum = Environment.ProcessorCount * 5; usageHistorySTP.Maximum = Environment.ProcessorCount * 5; } }
public void Execute(IJobExecutionContext context) { Stopwatch timer = new Stopwatch(); timer.Start(); logger.Debug("执行采集任务!!!!!!!!!!!!!!!"); try { using (MysqlDbContext dbcontext = new MysqlDbContext()) { var result = dbcontext.Database.SqlQuery<int>("select count(1) from uploaddatas "); logger.DebugFormat("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~采集表中共有{0}条数据 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", result.FirstOrDefault()); } } finally { } List<UploadData> alldata = new List<UploadData>(); int meterCount = 0; Stopwatch stopWatch = new Stopwatch(); try { MeterGroup metersgroup = ConfUtil.Meters(); if (metersgroup == null || metersgroup.RMeters == null || metersgroup.RMeters.Count == 0) { logger.Debug("执行采集任务<<<<没有发现表>>>>>"); return; } meterCount = metersgroup.RMeters.Sum(m => m.Value.Count) + metersgroup.VMeters.Count; logger.DebugFormat("执行采集任务!!!!!!!!!!!!!!! metersgroup == null [{0}]", metersgroup == null); DateTime taskgroup = DateTime.Now; stopWatch.Start(); //add by xlg var taskgroupMin = new DateTime(taskgroup.Year, taskgroup.Month, taskgroup.Day, taskgroup.Hour, taskgroup.Minute, 0); //one min only a collect job using (MysqlDbContext dbcontext = new MysqlDbContext()) { try { logger.DebugFormat("开始获取时间min!"); var dd = dbcontext.Database.SqlQuery<DateTime?>("select max(PowerDate) from uploaddatas").SingleOrDefault(); if (dd.HasValue) { if (taskgroupMin.Ticks <= dd.Value.Ticks) { logger.DebugFormat("***************开始获取时间min!,curr:{0}:{1} <= db:{2}:{3}", taskgroupMin, taskgroupMin.Ticks, dd.Value, dd.Value.Ticks); return; } } } catch (Exception ex) { logger.ErrorFormat("**获取时间min失败,{0}", ex); } } if (metersgroup != null && metersgroup.RMeters.Count > 0) { logger.DebugFormat("执行采集任务!!!!!!!!!!!!!!! metersgroup.RMeters.Count= [{0}]", metersgroup.RMeters.Count); int portCount = metersgroup.RMeters.Count; IWorkItemsGroup collectWorkItemsGroup = PoolsManager.GetCollectDataThreadPoolInstance().CreateWorkItemsGroup(portCount); IWorkItemResult<List<UploadData>>[] wirs = new IWorkItemResult<List<UploadData>>[portCount]; Amib.Threading.Func<StateData, List<UploadData>> func = new Amib.Threading.Func<StateData, List<UploadData>>(CollectPortData); logger.DebugFormat("执行采集任务!!!!!!!!!!!!!!! 建立线程工作项Count = [{0}]", portCount); for (var i = 0; i < portCount; i++) { string port = metersgroup.RMeters.Keys.ToList()[i]; logger.DebugFormat("执行采集任务!!!!!!!!!!!!!!! 建立线程工作项 [{0}] , [{1}], [{2}]", i, port, metersgroup.RMeters[port].Count); wirs[i] = collectWorkItemsGroup.QueueWorkItem<StateData, List<UploadData>>(func, new StateData { Port = port.ToUpper(), Group = taskgroup, Meters = metersgroup.RMeters[port] }); } logger.DebugFormat("执行采集任务!!!!!!!!!!!!!!! 执行所有工作项,等待全部完成"); bool success = SmartThreadPool.WaitAll(wirs, TimeSpan.FromMinutes(1), true); // logger.DebugFormat("执行采集任务!!!!!!!!!!!!!!! 线程池是否成功? [{0}]", success); if (success) { foreach (var wir in wirs) { alldata.AddRange(wir.Result); } //处理虚拟表(虚拟表计算失败,不影响实体表数据上传) try { //为虚拟表表达式准备数据 var paramz = new Dictionary<string, Dictionary<string, object>>(); foreach (var mm in alldata) { if (!paramz.ContainsKey("PowerValue")) { paramz["PowerValue"] = new Dictionary<string, object>(); } paramz["PowerValue"].Add(mm.DeviceId, mm.PowerValue); if (!paramz.ContainsKey("A1")) { paramz["A1"] = new Dictionary<string, object>(); } paramz["A1"].Add(mm.DeviceId, mm.A1); if (!paramz.ContainsKey("A2")) { paramz["A2"] = new Dictionary<string, object>(); } paramz["A2"].Add(mm.DeviceId, mm.A2); if (!paramz.ContainsKey("A3")) { paramz["A3"] = new Dictionary<string, object>(); } paramz["A3"].Add(mm.DeviceId, mm.A3); //add by xlg if (!paramz.ContainsKey("DiffMeterValuePre")) { paramz["DiffMeterValuePre"] = new Dictionary<string, object>(); } paramz["DiffMeterValuePre"].Add(mm.DeviceId, mm.DiffMeterValuePre); //add end } //生成虚拟表数据 if (metersgroup.VMeters != null && metersgroup.VMeters.Count > 0) { foreach (var mt in metersgroup.VMeters) { try { //check startdate and enddate add by xlgwr if (!(taskgroup >= mt.StartDate && taskgroup <= mt.EndDate)) { logger.DebugFormat("********************虚拟表数据:{0}不在有效日期内:{1} 至 {2}。 当前时间:{3}", mt.DeviceName, mt.StartDate, mt.EndDate, taskgroup); continue; } UploadData dd = new UploadData { PowerDate = taskgroupMin, Groupstamp = taskgroup.Ticks.ToString(), CustomerId = mt.CustomerId, DeviceCd = mt.DeviceCd, DeviceId = mt.DeviceId, PrePowerDate = taskgroupMin, Uploaded = 2 // by xlg 虚拟表不计算前值电量 }; Expression e = new Expression(mt.ComputationRule); e.Parameters = paramz["PowerValue"]; dd.PowerValue = (double)e.Evaluate(); e.Parameters = paramz["A1"]; dd.A1 = (double)e.Evaluate(); e.Parameters = paramz["A2"]; dd.A2 = (double)e.Evaluate(); e.Parameters = paramz["A3"]; dd.A3 = (double)e.Evaluate(); //add by xlg e.Parameters = paramz["DiffMeterValuePre"]; dd.DiffMeterValuePre = (double)e.Evaluate(); //end by xlg //判断虚拟表有否超过阈值 dd.ValueLevel = AlarmLevel(dd.PowerValue, mt); alldata.Add(dd); } catch (Exception ex) { logger.Error("虚拟表处理失败,DeviceId=" + mt.DeviceId, ex); } } } } catch (Exception ex) { logger.Error("虚拟表处理失败", ex); } }//success else { //add by xlg 2015-08-05 //同一组中,如果一表维修或已坏,old不会保存已采集的数据。 //修正:线程池为false,保存已采集到的数据。 if (_dataErrCollect.ContainsKey(taskgroup.Ticks.ToString())) { alldata.AddRange(_dataErrCollect[taskgroup.Ticks.ToString()]); var tmpAllcount = 0; foreach (var m in metersgroup.RMeters) { tmpAllcount += m.Value.Count(); } logger.ErrorFormat("执行采集任务!!!!!!总共:[{0}], [{1}] 已采集, [{2}] 有异常无法采集到.", tmpAllcount, alldata.Count, (tmpAllcount - alldata.Count)); } } } logger.DebugFormat("执行采集任务!!!!!!采集到数据 [{0}]条", alldata.Count); //存数据库 if (alldata.Count > 0) { using (MysqlDbContext dbcontext = new MysqlDbContext()) { dbcontext.Datas.AddRange(alldata); dbcontext.SaveChanges(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); logger.DebugFormat("########################执行采集任务!!!!!!共 [{0}]数据存储到本地数据库,UseTime(h:M:S.ms):{1}", alldata.Count, elapsedTime); } var maxlvl = alldata.Where(m => metersgroup.MMeter.Contains(m.DeviceId)).Max(m => m.ValueLevel);// context.JobDetail.JobDataMap.Put(Consts.AlarmLevelKey, maxlvl); } //add xlg remove bak if (_dataErrCollect != null) { if (_dataErrCollect.ContainsKey(taskgroup.Ticks.ToString())) { _dataErrCollect.Remove(taskgroup.Ticks.ToString()); }; } } catch (Exception ex) { logger.Error("串口采集失败", ex); //throw ex; } finally { //超过5分钟未上传,全报警。 try { if (alldata.Count() == meterCount) //数量一致,2分钟之前且5分钟以内有未上传数据,报警灯全亮 { using (MysqlDbContext dbcontext = new MysqlDbContext()) { var tmpDateNow = DateTime.Now; var tmpDateMin5 = tmpDateNow.AddMinutes(-5); var tmpDateMin2 = tmpDateNow.AddMinutes(-2); var lastData = dbcontext.Datas.Where(m => (m.PowerDate <= tmpDateMin2 && m.PowerDate >= tmpDateMin5 && (m.Uploaded | 1) == 0)).Count(); logger.DebugFormat("********有超过5分钟未上传,全报警。{0}.", lastData); if (lastData > 0) { context.JobDetail.JobDataMap.Put(Consts.AlarmLevelKey, -1); } } } else //数量不一致,报警灯全亮 { context.JobDetail.JobDataMap.Put(Consts.AlarmLevelKey, -1); } } catch (Exception ex) { logger.Error(ex.Message); } } timer.Stop(); logger.DebugFormat("********一次采集任务全程耗费时间:{0} 毫秒.", timer.ElapsedMilliseconds); }
/// <summary> /// This is a fairness-oriented group/time-based scheduler that monitors /// the execution time of threads for each configured group and favors /// threads for the configured groups that have the smallest accumulated /// execution time. /// </summary> /// <param name="s">the code to execute as a ThreadStart delegate</param> /// <param name="m">the maximum amount of threads</param> /// <param name="groupUUID">the UUID of the group</param> /// <param name="expiration">the time in milliseconds after which measurements are expunged</param> public IWorkItemResult <T> Spawn <T>(Amib.Threading.Func <T> s, uint m, UUID groupUUID, uint expiration) { // Don't accept to schedule bogus groups. if (groupUUID.Equals(UUID.Zero)) { return(default(IWorkItemResult <T>)); } if (smartThreadPool.InUseThreads > m) { return(default(IWorkItemResult <T>)); } var workItemPriority = WorkItemPriority.Normal; lock (GroupExecutionSetLock) { // Clear threads that are not restricted anymore due to expiration. GroupExecutionSet.RemoveWhere(o => (DateTime.UtcNow - o.TimeStamp).Milliseconds > expiration); var groupExecution = GroupExecutionSet.FirstOrDefault(o => o.GroupUUID.Equals(groupUUID)); // Adjust the priority depending on the time spent executing a command. if (GroupExecutionSet.Count > 1 && !groupExecution.Equals(default(GroupExecution))) { workItemPriority = threadRangePriority[ (int)(100L * groupExecution.ExecutionTime / GroupExecutionSet.Sum(o => o.ExecutionTime))]; } } // Spawn. var threadType = this.threadType; return(smartThreadPool.QueueWorkItem(() => { // protect inner thread var result = default(T); try { ThreadExecutuionStopwatch.Restart(); result = s(); ThreadExecutuionStopwatch.Stop(); lock (GroupExecutionSetLock) { // add or change the mean execution time for a group var groupExecution = GroupExecutionSet.AsParallel().FirstOrDefault(o => o.GroupUUID.Equals(groupUUID)); switch (!groupExecution.Equals(default(GroupExecution))) { case true: GroupExecutionSet.Remove(groupExecution); groupExecution.ExecutionTime = (groupExecution.ExecutionTime + ThreadExecutuionStopwatch.ElapsedMilliseconds) / 2; groupExecution.TimeStamp = DateTime.UtcNow; GroupExecutionSet.Add(groupExecution); break; default: GroupExecutionSet.Add(new GroupExecution { GroupUUID = groupUUID, ExecutionTime = ThreadExecutuionStopwatch.ElapsedMilliseconds, TimeStamp = DateTime.UtcNow }); break; } } } catch (Exception ex) { Corrade.Feedback( Reflection.GetDescriptionFromEnumValue( global::Corrade.Enumerations.ConsoleMessage.UNCAUGHT_EXCEPTION_FOR_THREAD), Reflection.GetNameFromEnumValue(threadType), ex.PrettyPrint()); } return result; }, workItemPriority)); }