/// <summary> /// This is a sequential scheduler that benefits from not blocking Corrade /// and guarrantees that any Corrade thread spawned this way will only execute /// until the previous thread spawned this way has completed. /// </summary> /// <param name="s">the code to execute as a ThreadStart delegate</param> /// <param name="m">the maximum amount of threads</param> /// <param name="millisecondsTimeout"> /// the timeout in milliseconds before considering the previous thread as vanished /// </param> public void SpawnSequential(Action s, uint m, uint millisecondsTimeout) { if (smartThreadPool.InUseThreads > m) { return; } var threadType = this.threadType; smartThreadPool.QueueWorkItem(() => { // protect inner thread try { SequentialThreadCompletedEvent.Wait((int)millisecondsTimeout); SequentialThreadCompletedEvent.Reset(); s(); SequentialThreadCompletedEvent.Set(); } catch (Exception ex) { Corrade.Feedback( Reflection.GetDescriptionFromEnumValue( global::Corrade.Enumerations.ConsoleMessage.UNCAUGHT_EXCEPTION_FOR_THREAD), Reflection.GetNameFromEnumValue(threadType), ex?.Message, ex.PrettyPrint(), ex?.InnerException?.Message); } }); }
/// <summary> /// This is an ad-hoc scheduler where threads will be executed in a /// first-come first-served fashion. /// </summary> /// <param name="s">the code to execute as a ThreadStart delegate</param> /// <param name="m">the maximum amount of threads</param> public void Spawn(Action s, uint m) { if (smartThreadPool.InUseThreads > m) { return; } var threadType = this.threadType; smartThreadPool.QueueWorkItem(() => { // protect inner thread try { s(); } catch (Exception ex) { Corrade.Feedback( Reflection.GetDescriptionFromEnumValue( global::Corrade.Enumerations.ConsoleMessage.UNCAUGHT_EXCEPTION_FOR_THREAD), Reflection.GetNameFromEnumValue(threadType), ex.PrettyPrint()); } }); }
/// <summary> /// 后台业务处理推送统一调用接口 /// 未持久化,可能出现丢失 /// </summary> /// <param name="func">委托方法</param> /// <param name="workItemPriority">任务等级,默认的是正常</param> public void Push(Amib.Threading.Action func, WorkItemPriority workItemPriority = WorkItemPriority.Normal) { _workItemsGroup.QueueWorkItem(func, workItemPriority); }
/// <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 void Spawn(Action s, uint m, UUID groupUUID, uint expiration) { // Don't accept to schedule bogus groups. if (groupUUID.Equals(UUID.Zero)) { return; } if (smartThreadPool.InUseThreads > m) { return; } 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; smartThreadPool.QueueWorkItem(() => { // protect inner thread try { ThreadExecutuionStopwatch.Restart(); 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()); } }, workItemPriority); }
public void Start(LicenseInfo licenseInfo) { if (isRunning) { return; } /* * 1. Get all active clients from db * 2. generate multi-thread for boardcasting message */ int activeClient = 0; try { isRunning = true; using (var db = new MyDbContext()) { #region Prepare Parameters db.Configuration.ProxyCreationEnabled = false; db.Configuration.LazyLoadingEnabled = false; var listClients = ListClientWithIPAddress(licenseInfo, out activeClient, true); List <RmsClient> broadcastClient = new List <RmsClient>(); foreach (var client in listClients) { if (client.UseLocalInfo == true) { var location = db.RmsLocations.Find(client.LocationId); if (location != null) { if (CanBroadCast(location)) { broadcastClient.Add(client); } } } else { broadcastClient.Add(client); } } // Log into RMS_Log_Monitoring int refID = AddLogMonitoring(activeClient, true, null); #region Initial Thread Pool var maxThreadConfig = db.RmsSystemConfigs.Find("MonitoringEngine.MaxThread"); int minThread = 1; int maxThread = 1; if (maxThreadConfig != null) { maxThread = Convert.ToInt32(maxThreadConfig.Value ?? maxThreadConfig.DefaultValue); if (maxThread > broadcastClient.Count) { maxThread = broadcastClient.Count; } } if (broadcastClient.Count > 0) { STPStartInfo stpStartInfo = new STPStartInfo(); stpStartInfo.MaxWorkerThreads = maxThread; stpStartInfo.IdleTimeout = 60 * 1000; stpStartInfo.MinWorkerThreads = minThread; stpStartInfo.PerformanceCounterInstanceName = "RMSCounter"; stpStartInfo.EnableLocalPerformanceCounters = true; stp = new SmartThreadPool(stpStartInfo); } #endregion foreach (var client in broadcastClient) { RmsClient _client = client; Amib.Threading.Action broadcastAliveMessage = () => { BroadcastAliveMessage(_client, refID); }; stp.QueueWorkItem(broadcastAliveMessage); } #endregion } } catch (Exception ex) { string exLicense = "License is invalid"; if (ex.Message.ToLower().IndexOf(exLicense.ToLower()) > -1) { // Log into RMS_Log_Monitoring AddLogMonitoring(activeClient, false, ex.Message); } throw new RMSWebException(this, "0500", "Start failed. " + ex.Message, ex, false); } finally { if (stp != null) { stp.WaitForIdle(); System.Threading.Thread.Sleep(1000); if (!stp.IsShuttingdown) { stp.Shutdown(); } stp.Dispose(); } isRunning = false; } }
public IWorkItemResult QueueWorkItem <T>(Action <T> action, T item, bool background = true, WorkItemPriority itemPriority = WorkItemPriority.Normal, ThreadPriority priority = ThreadPriority.Normal) { var pool = getPool(background, priority, itemPriority); return(pool.QueueWorkItem(action, item, itemPriority)); }