// Author: Gockner, Simon // Created: 2021-04-23 // Copyright(c) 2021 SimonG. All Rights Reserved. using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using Lib.ProcessManaging.Factories; using Lib.ProcessManaging.Interfaces; namespace Lib.ProcessManaging { public class ProcessManager : IProcessManager { private readonly IObservedProcessFactory _observedProcessFactory; private readonly CancellationTokenSource _cancellationTokenSource; private Thread? _monitorThread; public ProcessManager(IObservedProcessFactory observedProcessFactory) { _observedProcessFactory = observedProcessFactory; _cancellationTokenSource = new CancellationTokenSource(); Processes = new List(); } public List Processes { get; } public void Initialize() { using ManualResetEvent monitorReadyEvent = new(false); _monitorThread = new Thread(Monitor) { Name = "Process Monitor", IsBackground = true }; _monitorThread.Start(monitorReadyEvent); monitorReadyEvent.WaitOne(); } public IObservedProcess? GetProcessById(int id) => Processes.FirstOrDefault(p => p.Id == id); private void Monitor(object? state) { if (state is not ManualResetEvent monitorReadyEvent) return; monitorReadyEvent.Set(); while (!_cancellationTokenSource.IsCancellationRequested) { foreach (var process in Process.GetProcesses()) { if (Processes.Any(p => p.EqualsProcess(process))) continue; IObservedProcess observedProcess = _observedProcessFactory.Create(process); Processes.Add(observedProcess); ProcessStarted?.Invoke(this, observedProcess); } foreach (var observedProcess in Processes.ToList().Where(p => !Process.GetProcesses().Any(p.EqualsProcess))) { Processes.Remove(observedProcess); ProcessExited?.Invoke(this, observedProcess); //TestMe: is the passed process still usable? (disposed directly afterwards) observedProcess.Dispose(); } Thread.Sleep(1000); } } public event EventHandler? ProcessStarted; public event EventHandler? ProcessExited; public void Dispose() { Processes.ForEach(p => p.Dispose()); _cancellationTokenSource.Cancel(); _cancellationTokenSource.Dispose(); _monitorThread = null; } } }