public static void AddCache(string name, CacheManager cacheManager) { if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException(nameof(name)); } using (TimedLock.Lock(_dictionaryLockObject)) { if (CacheExists(name)) { throw new InvalidOperationException("cache already exists"); } _allCaches[name] = cacheManager ?? throw new ArgumentNullException(nameof(cacheManager)); } }
/// <summary> /// Returns the numer of caches /// </summary> /// <returns></returns> internal static CacheManager GetCache(string cacheName) { if (String.IsNullOrEmpty(cacheName)) { throw new ArgumentNullException(nameof(cacheName)); } using (TimedLock.Lock(_dictionaryLockObject)) { if (_allCaches.ContainsKey(cacheName)) { return(_allCaches[cacheName]); } } return(null); }
/// <summary> /// Retrieves a parameter value /// </summary> /// <param name="paramName">parameter name /// /// does not include the parameter seperator i.e. - or /</param> /// <param name="defaultValue">Default value if not found</param> /// <returns>Parameter value if found, otherwise defaultValue</returns> public static string GetOption(string paramName, string defaultValue = "") { if (_parameters == null) { throw new Exception("Parameters not initialised"); } using (TimedLock.Lock(_lockObject)) { if (_parameters.ContainsKey(_caseSensitive ? paramName : paramName.ToLower())) { return(_parameters[_caseSensitive ? paramName : paramName.ToLower()]); } } return(defaultValue); }
private void HookFolders() { using (TimedLock.Lock(_fileLockObject)) { foreach (string path in _hookedFolders) { FileSystemWatcher watcher = new System.IO.FileSystemWatcher(path); watcher.Changed += watcher_Changed; watcher.Deleted += watcher_Deleted; watcher.Renamed += watcher_Renamed; watcher.Created += watcher_Created; watcher.EnableRaisingEvents = true; watcher.IncludeSubdirectories = true; _watchedFolders.Add(watcher); } } }
/// <summary> /// /// </summary> /// <param name="session"></param> public static void UpdateSession(UserSession session) { if (session.Status == SessionStatus.Updated) { return; } using (TimedLock.Lock(_tempLockObject)) { _tempUserSessions.Add(session); if (session.Status == SessionStatus.Continuing) { session.Status = SessionStatus.Initialising; } } }
/// <summary> /// Returns the number of items in the cache /// </summary> /// <param name="index">Index of cache</param> /// <returns>integer</returns> public static int GetCacheCount(int index) { int i = 0; using (TimedLock.Lock(_dictionaryLockObject)) { foreach (KeyValuePair <string, CacheManager> cManager in _allCaches) { if (i == index) { return(cManager.Value.Count); } i++; } } throw new IndexOutOfRangeException(); }
/// <summary> /// Cancel's a running thread /// </summary> /// <param name="name">Name of the thread</param> public static void Cancel(string name) { if (_cpuUsage == null) { throw new InvalidOperationException("ThreadManager must be initialised"); } using (TimedLock.Lock(_lockObject, new TimeSpan(0, 0, 30))) { foreach (ThreadManager item in _threadList) { if (item.Name == name && !item.MarkedForRemoval) { item.CancelThread(); break; } } } }
/// <summary> /// Checks wether a thread with a specific name exists and if so returns it /// </summary> /// <param name="name">Name of Thread /// /// Exact match which is case sensistive</param> /// <returns>ThreadManager object if thread exists, otherwise null</returns> public static ThreadManager Find(string name) { if (_cpuUsage == null) { throw new InvalidOperationException("ThreadManager must be initialised"); } using (TimedLock.Lock(_lockObject)) { foreach (ThreadManager item in _threadList) { if (item.Name == name && !item.MarkedForRemoval) { return(item); } } } return(null); }
/// <summary> /// Adds a thread to the list of threads being watched /// </summary> /// <param name="thread">Thread to start watching</param> public void ThreadAdd(ThreadManager thread) { using (TimedLock.Lock(_lockObject)) { foreach (ThreadManager watchedThread in _watchedThreads) { if (thread.ThreadID == watchedThread.ThreadID) { return; } } _watchedThreads.Add(thread); if (!_threadTimes.ContainsKey(thread.ID)) { _threadTimes.Add(thread.ID, new TimeSpan()); } } }
/// <summary> /// PageView is used whenever a user visits a page /// </summary> /// <param name="page">Current page being viewed</param> /// <param name="referrer">Current Referrer</param> /// <param name="isPostBack">Is Post Back</param> public void PageView(string page, string referrer, bool isPostBack) { using (TimedLock.Lock(_pageViewLockObject)) { PageViewData newPageView = new PageViewData(page, referrer, isPostBack); _pageViews.Add(newPageView); if (UserSessionManager.SaveImmediately) { newPageView.SaveStatus = Classes.SaveStatus.RequiresSave; UserSessionManager.Instance.RaiseSavePage(this, newPageView); } else { newPageView.SaveStatus = SaveStatus.Pending; } } int pages = _pageViews.Count - 1; if (pages >= 1) { // calculate page time for previous page PageViewData previousPage = _pageViews[pages - 1]; previousPage.TotalTime = DateTime.UtcNow - previousPage.TimeStamp; // not a bounce as already moved onto another page if (Bounced) { Bounced = false; } previousPage.SaveStatus = Classes.SaveStatus.RequiresSave; PageSaveStatus = Classes.SaveStatus.RequiresSave; } CurrentPage = page; }
public static void Initialise(ICpuUsage cpuUsage) { // only initialize once if (_cpuUsage != null) { return; } _cpuUsage = cpuUsage ?? throw new ArgumentNullException(nameof(cpuUsage)); using (TimedLock.Lock(_lockObject)) { _globalCancelRequested = false; if (_threadManager == null) { _threadManager = new ThreadManagerManager(); ThreadStart(_threadManager, "Thread Manager - Management Thread", ThreadPriority.BelowNormal, false); } if (_threadAbortManager == null) { _threadAbortManager = new ThreadAbortManager(); ThreadStart(_threadAbortManager, "Thread Abort - Management Thread", ThreadPriority.Lowest, false); } if (_threadCacheManager == null) { _threadCacheManager = new ThreadCacheManager(); Classes.ThreadManager.ThreadStart(_threadCacheManager, "Cache Management Thread", ThreadPriority.Lowest); } } }
/// <summary> /// Starts a new thread /// </summary> /// <param name="thread"></param> /// <param name="name"></param> /// <param name="priority"></param> /// <param name="addToList"></param> private static void ThreadStart(ThreadManager thread, string name, ThreadPriority priority, bool addToList, bool isBackgroundThread) { if (_cpuUsage == null) { throw new InvalidOperationException("ThreadManager must be initialised"); } if (thread == null) { throw new ArgumentNullException("thread parameter can not be null"); } // generic properties thread.ThreadFinishing += thread_ThreadFinishing; thread.IsBackGround = isBackgroundThread; thread._thread = new Thread(thread.ThreadRun); thread._thread.IsBackground = isBackgroundThread; thread._thread.Name = name; if (addToList) { lock (_lockObject) { if (_threadList.Count >= _maximumRunningThreads) { if (_allowThreadsToPool) { if (_threadPool.Count > _maximumThreadPoolSize) { throw new Exception("Thread Pool Count exceeded"); } _threadPool.Add(thread); // notify listners that a thread has been added to the queue ThreadQueueAddItem?.Invoke(null, new ThreadManagerEventArgs(thread)); return; } else { throw new Exception("Maximum running threads exceeded."); } } } } thread._thread.Priority = priority; thread._thread.IsBackground = isBackgroundThread; thread._thread.Start(thread._parameters); if (addToList) { using (TimedLock.Lock(_lockObject)) { thread._lastCommunication = DateTime.UtcNow; //_countOfThreads++; //_threadList.Add(thread); } } }
/// <summary> /// Thread run method /// </summary> /// <param name="parameters">Thread parameters</param> /// <returns>true if execution should continue, otherwise false</returns> protected override bool Run(object parameters) { // move sessions from temp storage to processing storage using (TimedLock.Lock(_tempLockObject)) { for (int i = _tempUserSessions.Count - 1; i >= 0; i--) { using (TimedLock.Lock(_sessionLockObject)) { _userSessions.Add(_tempUserSessions[i]); System.Threading.Thread.Sleep(0); } _tempUserSessions.RemoveAt(i); } } using (TimedLock.Lock(_sessionLockObject)) { for (int i = _userSessions.Count - 1; i >= 0; i--) { UserSession session = _userSessions[i]; switch (session.Status) { case SessionStatus.Updated: _userSessions.Remove(session); break; case SessionStatus.Initialising: if (InitialiseWebsite) { InitialiseSession(session); } _userSessions.Remove(session); break; case SessionStatus.Closing: FinaliseSession(session); _userSessions.Remove(session); break; } } } if (_loopCounter % 3 == 0) { if (OnSessionSave != null && UserSessions != null) { foreach (CacheItem item in UserSessions.Items) { UserSession session = (UserSession)item.GetValue(true); // every 15 seconds or so save the data using (TimedLock.Lock(_sessionLockObject)) { using (TimedLock.Lock(session)) { if (session.SaveStatus == SaveStatus.RequiresSave || session.PageSaveStatus == SaveStatus.RequiresSave) { RaiseSessionSave(session); session.PageSaveStatus = SaveStatus.Saved; } } } System.Threading.Thread.Sleep(0); } } if (_loopCounter > Int64.MaxValue - 50) { _loopCounter = Int64.MinValue; } } _loopCounter++; return(!this.HasCancelled()); }
protected override bool Run(object parameters) { // check to see if timeout value of cancel has expired, if so, kill the thread using (TimedLock.Lock(_lockObject)) { _cpuUsage.GetProcessUsage(); for (int i = _threadList.Count - 1; i >= 0; i--) { ThreadManager item = _threadList[i]; if (_checkForHangingThreads) { TimeSpan hangingSpan = DateTime.UtcNow - item._lastCommunication; if (item.HangTimeout > 0 && !item._cancel && hangingSpan.TotalMinutes > item.HangTimeout) { //set time out long enough for the thread to clear itself out // if it doesn't then we will force the closure item.CancelThread(10000, true); } } if (item.MarkedForRemoval) { item.ThreadFinishing -= thread_ThreadFinishing; } if (item._cancel) { TimeSpan span = DateTime.UtcNow - item._cancelRequested; if (span.TotalMilliseconds > item._cancelTimeoutMilliseconds) { if (!item.MarkedForRemoval) { _countOfThreads--; item.ThreadFinishing -= thread_ThreadFinishing; _threadList.Remove(item); } RaiseThreadForcedToClose(item); _abortPool.Add(item); } } // if there is enough space, can we run one of the threads in the pool? if (AllowThreadPool && _threadPool.Count > 0) { while (_threadList.Count < MaximumRunningThreads) { ThreadManager nextRunItem = _threadPool[0]; _threadPool.RemoveAt(0); RaiseThreadQueueRemoveItem(nextRunItem); ThreadStart(nextRunItem, nextRunItem.Name, nextRunItem._thread.Priority, _thread.IsBackground); } } } } return(!HasCancelled()); }
/// <summary> /// Thread execution method /// </summary> /// <param name="parameters"></param> protected void ThreadRun(object parameters) { ThreadID = _cpuUsage.GetCurrentThreadId(); ID = Thread.CurrentThread.ManagedThreadId; if (_monitorCPUUsage) { _cpuUsage.ThreadAdd(this); } TimeStart = DateTime.UtcNow; // is the start being delayed if (_delayStart > 0) { // need to ensure that if the app is closed prior to the thread being // run then we provide a mechanism for the thread to close DateTime continueTime = DateTime.UtcNow.AddMilliseconds(_delayStart); while (continueTime > DateTime.UtcNow) { Thread.Sleep(100); if (HasCancelled()) { break; } } } _lastRun = DateTime.UtcNow.AddDays(RunAtStartup ? -1 : 0); DateTime lastPing = DateTime.UtcNow; using (TimedLock.Lock(_lockObject)) { _threadList.Add(this); _countOfThreads++; } RaiseThreadStart(this); try { while (true) // always loop { try { //have we been asked to cancel the thread? if (_cancel) { return; } TimeSpan span = DateTime.UtcNow - _lastRun; // run the thread if (span.TotalMilliseconds > RunInterval.TotalMilliseconds) { if (!Run(_parameters)) { return; } _lastRun = DateTime.UtcNow; } span = DateTime.UtcNow - lastPing; if (span.TotalSeconds > 30) { lastPing = DateTime.UtcNow; Ping(); } // play niceley with everyone else Thread.Sleep(SleepInterval); } catch (ThreadAbortException) { return; } catch (Exception error) { RaiseOnException(error); if (!ContinueIfGlobalException) { throw; } } } } finally { TimeFinish = DateTime.UtcNow; if (_monitorCPUUsage && _cpuUsage != null) { _cpuUsage.ThreadRemove(this); } using (TimedLock.Lock(_lockObject)) { _threadList.Remove(this); _countOfThreads--; } RaiseThreadFinished(this); } }
/// <summary> /// Retrieves the total process usage for the current process /// </summary> /// <returns></returns> public decimal GetProcessUsage() { decimal Result = _cpuUsage; if (!EnoughTimePassed) { return(Result); } #if WINDOWS_ONLY using (TimedLock.Lock(_lockObject)) { ThreadCPUChanged = false; ComTypes.FILETIME sysIdle, sysKernel, sysUser; Process process = Process.GetCurrentProcess(); TimeSpan procTime = process.TotalProcessorTime; if (!GetSystemTimes(out sysIdle, out sysKernel, out sysUser)) { return(Result); } // get thread times foreach (ProcessThread thread in Process.GetCurrentProcess().Threads) { if (_threadTimes.ContainsKey(thread.Id)) { _threadTimes[thread.Id] = thread.TotalProcessorTime; } } Int64 sysKernelDiff = SubtractTimes(sysKernel, _prevSysKernel); Int64 sysUserDiff = SubtractTimes(sysUser, _prevSysUser); Int64 sysTotal = sysKernelDiff + sysUserDiff; Int64 processTotal = procTime.Ticks - _prevProcTotal.Ticks; if (sysTotal > 0 && processTotal > 0) { _cpuUsage = (100.0m * processTotal) / sysTotal; } else { _cpuUsage = 0; } _prevProcTotal = procTime; _prevSysKernel = sysKernel; _prevSysUser = sysUser; decimal otherUsage = 0.0m; foreach (ThreadManager watchedThread in _watchedThreads) { TimeSpan span; if (_threadTimes.ContainsKey(watchedThread.ID)) { span = _threadTimes[watchedThread.ID]; } else { span = new TimeSpan(); } watchedThread.CPUUsageChanged = false; watchedThread.UpdateThreadUsage(processTotal, sysTotal, span); if (!ThreadCPUChanged && watchedThread.CPUUsageChanged) { ThreadCPUChanged = true; } otherUsage += watchedThread.ProcessCpuUsage; } OtherProcessCPUUsage = Utilities.CheckMinMax(100 - otherUsage, 0.0m, 100.00m); //_cpuUsage - otherUsage; _lastRun = DateTime.UtcNow; Result = _cpuUsage; } if (ThreadCPUChanged) { ThreadManager.RaiseThreadCpuChanged(); } #endif return(Result); }