Maxim Gershkovich
Maxim Gershkovich

Reputation: 47149

Threadpool with endless worker threads

I have class which implements an endless worker thread like this example, in my case representing a body. During runtime I will have between 0 and ~8 instances live at any time with instances constantly being created and destroyed.

Most of the time this class has a lifecycle of 30 seconds to 5 minutes but occasionally there may be a number of instances created and destroyed in a relatively short period of time. This is where I tend to run into performance issues given the low spec hardware this code is running on.

I would now like to rewrite the behavior so that I use a ThreadPool for my collection of running workers and I am struggling to find the correct way to structure the code.

Basically the code I have at the moment is something like

public class BodyCollection : IReadOnlyDictionary<ulong, TrackedBody>
{
    public void Update() 
    {
        if (createNew) 
        {
           var body = new TrackedBody();
           body.BeginTracking();
           this.Add(1234, body);
        }

        if (remove) 
        {
            TrackedBody body = this[1234];
            body.StopTracking();
            this.Remove(body);
        }
    }
}

public class TrackedBody
{
    private readonly Thread _BiometricsThread;
    private volatile bool _Continue = true;

    public TrackedBody() 
    {
        _BiometricsThread = new Thread(RunBiometricsThread);
    }

    public void BeginTracking()
    {
        _BiometricsThread.Start();
    }

    public void StopTracking() 
    {    
        _Continue = false;
    }

    private void RunBiometricsThread()
    {
        while(_Continue) 
        {
            System.Threading.Thread.Sleep(1000);
        }
    }
}

So how do I re-write the above to utilize a ThreadPool correctly and so that I can cancel running threads on the ThreadPool as required? Do I use CancellationTokens or ManualResetEvents to control the threads?

Upvotes: 0

Views: 457

Answers (1)

Gusdor
Gusdor

Reputation: 14334

I strongly believe you should be using more modern methods of asynchronous programming. We are going to use the Task Parallel Library here because it gives you the features you want for free:

  • Tracking completion
  • Cancellation
  • Thread pool

public class TrackedBody
{     
    public Task BeginTrackingAsync(CancellationToken cancellation)
    {
        return Task.Run(() => RunBiometricsThread(cancellation));
    }

    private void RunBiometricsThread(CancellationToken cancellation)
    {
        while(!cancellation.IsCancellationRequested) 
        {
            Task.Delay(1000, cancellation);
        }
    }
}

Note that I have removed the async keyword. This was doing nothing on its own.

You can use the task to track the state of the ongoing work. You can use the cancellation token to stop all work.

Upvotes: 1

Related Questions