From 0b98638cd5fc61deac8bf908121d606c05c16dfc Mon Sep 17 00:00:00 2001 From: glax Date: Thu, 16 Jan 2025 22:36:52 +0100 Subject: [PATCH] Less CPU usage by creating tasks per action, instead of thread --- CShocker.sln.DotSettings.user | 1 + CShocker/CShocker.csproj | 2 +- CShocker/Devices/Abstract/Api.cs | 33 +++++++++++++++++--------------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/CShocker.sln.DotSettings.user b/CShocker.sln.DotSettings.user index 5705f12..1b4eec9 100644 --- a/CShocker.sln.DotSettings.user +++ b/CShocker.sln.DotSettings.user @@ -1,5 +1,6 @@  True + ForceIncluded ForceIncluded <AssemblyExplorer> <Assembly Path="C:\Users\Glax\RiderProjects\GlaxLogger\GlaxLogger\bin\Debug\net7.0\GlaxLogger.dll" /> diff --git a/CShocker/CShocker.csproj b/CShocker/CShocker.csproj index 351d15a..0781cc3 100644 --- a/CShocker/CShocker.csproj +++ b/CShocker/CShocker.csproj @@ -6,7 +6,7 @@ Glax https://github.com/C9Glax/CShocker git - 3.0.2 + 3.1.0 net8.0;net9.0 latestmajor https://github.com/C9Glax/CShocker diff --git a/CShocker/Devices/Abstract/Api.cs b/CShocker/Devices/Abstract/Api.cs index d4552c5..6a710e4 100644 --- a/CShocker/Devices/Abstract/Api.cs +++ b/CShocker/Devices/Abstract/Api.cs @@ -10,10 +10,9 @@ public abstract class Api : IDisposable // ReSharper disable 4 times MemberCanBePrivate.Global -> Exposed protected ILogger? Logger; public readonly DeviceApi ApiType; - private readonly Queue> _queue = new(); - private bool _workOnQueue = true; + private Queue order = new(); + private Dictionary tasks = new(); // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable - private readonly Thread _workQueueThread; private const short CommandDelay = 50; internal readonly IntegerRange ValidIntensityRange, ValidDurationRange; @@ -38,7 +37,12 @@ public abstract class Api : IDisposable foreach (Shocker shocker in shockers) { this.Logger?.Log(LogLevel.Debug, $"Enqueueing {action} Intensity: {intensity} Duration: {duration}\nShocker:\n{shocker}"); - _queue.Enqueue(new(action, shocker, intensity, duration)); + ValueTuple tuple = new(action, shocker, intensity, duration); + DateTime now = DateTime.Now; + Task t = new (() => ExecuteTask(now, tuple)); + order.Enqueue(now); + tasks.Add(now, t); + t.Start(); } } @@ -50,19 +54,17 @@ public abstract class Api : IDisposable this.Logger = logger; this.ValidIntensityRange = validIntensityRange; this.ValidDurationRange = validDurationRange; - this._workQueueThread = new Thread(QueueThread); - this._workQueueThread.Start(); } - private void QueueThread() + private void ExecuteTask(DateTime when, ValueTuple tuple) { - while (_workOnQueue) - if (_queue.Count > 0 && _queue.Dequeue() is { } action) - { - this.Logger?.Log(LogLevel.Information, $"Executing: {Enum.GetName(action.Item1)} Intensity: {action.Item3} Duration: {action.Item4}\nShocker:\n{action.Item2}"); - ControlInternal(action.Item1, action.Item2, action.Item3, action.Item4); - Thread.Sleep(action.Item4 + CommandDelay); - } + while (order.First() != when) + Thread.Sleep(CommandDelay); + this.Logger?.Log(LogLevel.Information, $"Executing: {Enum.GetName(tuple.Item1)} Intensity: {tuple.Item3} Duration: {tuple.Item4}\nShocker:\n{tuple.Item2}"); + ControlInternal(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4); + Thread.Sleep(tuple.Item4); + tasks.Remove(when); + order.Dequeue(); } public void SetLogger(ILogger? logger) @@ -92,6 +94,7 @@ public abstract class Api : IDisposable public void Dispose() { - _workOnQueue = false; + foreach ((DateTime when, Task? task) in tasks) + task?.Dispose(); } } \ No newline at end of file