mirror of
https://github.com/ckaczor/ProcessCpuUsageStatusWindow.git
synced 2026-01-13 17:23:02 -05:00
160 lines
5.3 KiB
C#
160 lines
5.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Timers;
|
|
using System.Windows.Threading;
|
|
|
|
namespace ProcessCpuUsageStatusWindow
|
|
{
|
|
public class ProcessCpuUsageWatcher
|
|
{
|
|
#region Update delegate
|
|
|
|
public delegate void ProcessListUpdatedDelegate(Dictionary<string, ProcessCpuUsage> currentProcessList);
|
|
|
|
#endregion
|
|
|
|
#region Member variables
|
|
|
|
private Dispatcher _dispatcher;
|
|
private Timer _processUpdateTimer;
|
|
private ProcessListUpdatedDelegate _processListUpdatedCallback;
|
|
private PerformanceCounterCategory _processCategory;
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
public Dictionary<string, ProcessCpuUsage> CurrentProcessList;
|
|
|
|
#endregion
|
|
|
|
#region Initialize and terminate
|
|
|
|
public void Initialize(TimeSpan updateInterval, ProcessListUpdatedDelegate callback, Dispatcher dispatcher)
|
|
{
|
|
_dispatcher = dispatcher;
|
|
|
|
// Create a new dictionary for the process list
|
|
CurrentProcessList = new Dictionary<string, ProcessCpuUsage>();
|
|
|
|
// Get the category for process performance info
|
|
_processCategory = PerformanceCounterCategory.GetCategories().FirstOrDefault(category => category.CategoryName == "Process V2");
|
|
|
|
if (_processCategory == null)
|
|
return;
|
|
|
|
// Read the entire category
|
|
var processCategoryData = _processCategory.ReadCategory();
|
|
|
|
// Get the processor time data
|
|
var processorTimeData = processCategoryData["% processor time"];
|
|
|
|
if (processorTimeData?.Values == null)
|
|
return;
|
|
|
|
// Loop over each instance and add it to the list
|
|
foreach (InstanceData instanceData in processorTimeData.Values)
|
|
{
|
|
// Create a new process usage object
|
|
var processCpuUsage = new ProcessCpuUsage(instanceData);
|
|
|
|
// Add to the list
|
|
CurrentProcessList.Add(processCpuUsage.ProcessName, processCpuUsage);
|
|
}
|
|
|
|
// Save the update callback
|
|
_processListUpdatedCallback = callback;
|
|
|
|
// Create a timer to update the process list
|
|
_processUpdateTimer = new Timer(updateInterval.TotalMilliseconds) { AutoReset = false };
|
|
_processUpdateTimer.Elapsed += HandleProcessUpdateTimerElapsed;
|
|
_processUpdateTimer.Start();
|
|
}
|
|
|
|
public void Terminate()
|
|
{
|
|
// Get rid of the timer
|
|
if (_processUpdateTimer != null)
|
|
{
|
|
_processUpdateTimer.Stop();
|
|
_processUpdateTimer.Dispose();
|
|
}
|
|
|
|
// Clear the callback
|
|
_processListUpdatedCallback = null;
|
|
|
|
// Clear the process list
|
|
CurrentProcessList = null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Timer handling
|
|
|
|
private void HandleProcessUpdateTimerElapsed(object sender, ElapsedEventArgs e)
|
|
{
|
|
// Update the current process list
|
|
UpdateCurrentProcessList();
|
|
|
|
// Restart the timer
|
|
_processUpdateTimer.Start();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Process list management
|
|
|
|
private void UpdateCurrentProcessList()
|
|
{
|
|
// Get a timestamp for the current time that we can use to see if a process was found this check
|
|
var checkStart = DateTime.Now;
|
|
|
|
// Read the entire category
|
|
var processCategoryData = _processCategory.ReadCategory();
|
|
|
|
// Get the processor time data
|
|
var processorTimeData = processCategoryData["% processor time"];
|
|
|
|
if (processorTimeData?.Values == null)
|
|
return;
|
|
|
|
// Loop over each instance and add it to the list
|
|
foreach (InstanceData instanceData in processorTimeData.Values)
|
|
{
|
|
// See if we already know about this process
|
|
if (CurrentProcessList.ContainsKey(instanceData.InstanceName))
|
|
{
|
|
// Get the previous process usage object
|
|
var processCpuUsage = CurrentProcessList[instanceData.InstanceName];
|
|
|
|
// Update the CPU usage with new data
|
|
processCpuUsage.UpdateCpuUsage(instanceData, checkStart);
|
|
}
|
|
else
|
|
{
|
|
// Create a new CPU usage object
|
|
var processCpuUsage = new ProcessCpuUsage(instanceData, checkStart);
|
|
|
|
// Add it to the list
|
|
CurrentProcessList.Add(processCpuUsage.ProcessName, processCpuUsage);
|
|
}
|
|
}
|
|
|
|
// Build a list of cached processes we haven't found this check
|
|
var oldProcessList = (from processCpuUsage in CurrentProcessList
|
|
where processCpuUsage.Value.LastFound != checkStart
|
|
select processCpuUsage.Key).ToList();
|
|
|
|
// Loop over the list and remove the old process
|
|
foreach (var key in oldProcessList)
|
|
CurrentProcessList.Remove(key);
|
|
|
|
// Invoke the callback with the new current process list
|
|
_dispatcher.InvokeAsync(() => _processListUpdatedCallback.Invoke(CurrentProcessList));
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |