Fix WorkerThread hanging on dispose

wait-with-timeout-zero
Clive Galway 2 years ago
parent 150c1bac17
commit 339d51f573

@ -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();

@ -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;
}

@ -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<Action> Actions { get; }
public WorkerThread()
{
Actions = new BlockingCollection<Action>();
_worker = new Thread(Run);
_running = false;
}
public BlockingCollection<Action> 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();
}
}
}

Loading…
Cancel
Save