From 339d51f573d7b6e944c940c861f6b737667a0495 Mon Sep 17 00:00:00 2001 From: Clive Galway Date: Fri, 21 Jan 2022 19:57:53 +0000 Subject: [PATCH] Fix WorkerThread hanging on dispose --- .../DeviceHandlers/DeviceHandler.cs | 3 +- .../DeviceHandlers/MouseHandler.cs | 3 -- C#/AutoHotInterception/WorkerThread.cs | 39 +++++++------------ 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/C#/AutoHotInterception/DeviceHandlers/DeviceHandler.cs b/C#/AutoHotInterception/DeviceHandlers/DeviceHandler.cs index ece90a3..c48f97f 100644 --- a/C#/AutoHotInterception/DeviceHandlers/DeviceHandler.cs +++ b/C#/AutoHotInterception/DeviceHandlers/DeviceHandler.cs @@ -38,7 +38,6 @@ namespace AutoHotInterception.DeviceHandlers if (!mappingOptions.Concurrent && !WorkerThreads.ContainsKey(code)) { WorkerThreads.TryAdd(code, new WorkerThread()); - WorkerThreads[code].Start(); } _isFiltered = true; } @@ -69,7 +68,6 @@ namespace AutoHotInterception.DeviceHandlers if (!mappingOptions.Concurrent && DeviceWorkerThread == null) { DeviceWorkerThread = new WorkerThread(); - DeviceWorkerThread.Start(); } _isFiltered = true; } @@ -84,6 +82,7 @@ namespace AutoHotInterception.DeviceHandlers if (!AllButtonsMapping.Concurrent && DeviceWorkerThread != null) { DeviceWorkerThread.Dispose(); + DeviceWorkerThread = null; } AllButtonsMapping = null; DisableFilterIfNeeded(); diff --git a/C#/AutoHotInterception/DeviceHandlers/MouseHandler.cs b/C#/AutoHotInterception/DeviceHandlers/MouseHandler.cs index d34a846..63a3120 100644 --- a/C#/AutoHotInterception/DeviceHandlers/MouseHandler.cs +++ b/C#/AutoHotInterception/DeviceHandlers/MouseHandler.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; using AutoHotInterception.Helpers; @@ -46,7 +45,6 @@ namespace AutoHotInterception.DeviceHandlers if (!mappingOptions.Concurrent && !WorkerThreads.ContainsKey(7)) { WorkerThreads.TryAdd(7, new WorkerThread()); - WorkerThreads[7].Start(); } _isFiltered = true; } @@ -76,7 +74,6 @@ namespace AutoHotInterception.DeviceHandlers if (!mappingOptions.Concurrent && !WorkerThreads.ContainsKey(8)) { WorkerThreads.TryAdd(8, new WorkerThread()); - WorkerThreads[8].Start(); } _isFiltered = true; } diff --git a/C#/AutoHotInterception/WorkerThread.cs b/C#/AutoHotInterception/WorkerThread.cs index d073aed..473a318 100644 --- a/C#/AutoHotInterception/WorkerThread.cs +++ b/C#/AutoHotInterception/WorkerThread.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -10,40 +7,32 @@ namespace AutoHotInterception { class WorkerThread : IDisposable { - private readonly Thread _worker; - private volatile bool _running; + private Task _worker; + private CancellationTokenSource _cancellationToken; + public BlockingCollection Actions { get; } public WorkerThread() { Actions = new BlockingCollection(); - _worker = new Thread(Run); - _running = false; - } - - public BlockingCollection Actions { get; } - - public void Dispose() - { - if (!_running) return; - _running = false; - _worker.Abort(); - _worker.Join(); - } - - public void Start() - { - if (_running) return; - _running = true; + _cancellationToken = new CancellationTokenSource(); + _worker = new Task(Run, _cancellationToken.Token); _worker.Start(); } - private void Run() + private void Run(Object obj) { - while (_running) + var token = (CancellationToken)obj; + while (!token.IsCancellationRequested) { var action = Actions.Take(); action.Invoke(); } } + + public void Dispose() + { + _cancellationToken.Cancel(); + _cancellationToken.Dispose(); + } } }