Home > Blockchain >  Implementing Your ThreadPool
Implementing Your ThreadPool

Time:08-18

A ThreadPool is created that does all the work on one thread and notifies when the work is done. The thread is started and the methods Execute1 and Execute2 are not displayed, but Done1 and Done2 are not displayed, although in the debugger execution reaches handle.Finished.

public class MyThreadPool
{
    private readonly Thread[] _Threads;

    public delegate void ParameterizedThreadStart(object? obj);
    public MyThreadPool()
    {
        _Threads = new Thread[1];
    }

    public HandleEvent QueueUserWorkItem(System.Threading.ParameterizedThreadStart callBack)
    {
        var thread = new Thread(callBack) { IsBackground = true };
        _Threads[0] = thread;
        _Threads[0].Start();
        return new HandleEvent();
    }
}

public class HandleEvent : EventArgs    
{
    public event EventHandler? Finished;
    protected virtual void onFinished(object e, EventArgs s)
    {
        Finished?.Invoke(this, EventArgs.Empty);
    }

    public HandleEvent ()
    {
        onFinished("sddd", EventArgs.Empty);  
    }
}
public static class Program
{
    public static void Main()
    {
    static void ExecuteMethod2(object execute)
    {
        Console.WriteLine("Hello from the thread pool.");
    }

    static void ExecuteMethod1(object execute)
    {
        Console.WriteLine("Hello from the thread pool.");
    }

    var thread_pool = new MyThreadPool();

    var handle1 = thread_pool.QueueUserWorkItem(ExecuteMethod1);
    handle1.Finished  = (o, a) => { Console.WriteLine($"Done 1"); };

    var handle2 = thread_pool.QueueUserWorkItem(ExecuteMethod2);
    handle2.Finished  = (o, a) => { Console.WriteLine($"Done 2"); };
  }
}

CodePudding user response:

The problem is that the onFinished method is never called. This should be called once the thread has completed execution of its callback, but it is not. For this to work the QueueUserWorkItem needs to wrap the callback in a method that does this, i.e. something like

var result = new HandleEvent();
void localExecute(object execute)
{
    callBack(execute); // run the actual work
    result.onFinished(); // Raise the finished method
}
var thread = new Thread(localExecute) { IsBackground = true };
_Threads[0] = thread;
_Threads[0].Start();
return result ;

However, there are other issues:

  1. There is no actual thread pooling going on. The point of a threadpool is that threads are expensive to create, so you keep them around in a pool instead of creating new ones. The threads should be in a blocked state while in the pool, so the pool can assign the thread a task and wake it when needed.
  2. There is no synchronization going on, so the program may very well complete before all threads are done. So you may want to return something like a ManualResetEvent that can be waited on, instead of your own custom event.
  3. There is rarely any reason to implement your own thread pool, and doing so well is quite difficult. So I really hope you are doing this for educational purposes, and do not intend to use the result in real life.
  • Related