Reputation: 2924
I am trying to write a Custom Thread Pool object to run a certain function that might take long time.
I have written the following to code to run a simulation:
namespace TPConsoleTest
{
class Program
{
private static MyThreadPool tp = null;
static void Main(string[] args)
{
// Create new thread pool
tp = new MyThreadPool(5);
// Register on completion event
tp.OnThreadDone += tp_OnThreadDone;
for (int i = 0; i < 20; i++)
{
tp.AddThread(i);
}
// Wait for exit
Console.ReadKey();
}
static void tp_OnThreadDone(string name, int ix)
{
// Remove finished thread from pool
tp.RemoveThread(name);
// Write messsage
Console.WriteLine("Thread {0} ended for : #{1}", name, ix);
}
}
}
namespace TPConsoleTest
{
class MyThreadPool
{
private IList<Thread> _threads;
private int _maxThreads = 0;
public bool IsPoolAvailable
{
get
{
if (this._threads != null && this._threads.Count(x => x.IsAlive) < this._maxThreads)
return true;
else
return false;
}
}
public delegate void ThreadDone(string name, int id);
public event ThreadDone OnThreadDone;
public MyThreadPool(int maxThreadCount)
{
// Set maximum number of threads
this._maxThreads = maxThreadCount;
// Initialize pool
this._threads = new List<Thread>();
}
public void AddThread(int ix)
{
// If maximum number is reached, wait for an empty slot
while (!this.IsPoolAvailable)
{
Thread.Sleep(100);
}
// Create a unique name for the threae
string tName = Guid.NewGuid().ToString();
Thread t = new Thread(() =>
{
// Do this time-consuming operation
MyWorker w = new MyWorker();
w.DoWork(tName, ix);
});
t.IsBackground = true;
t.Name = tName;
t.Start();
// Add to pool
this._threads.Add(t);
// Fire event when done
if (OnThreadDone != null)
OnThreadDone(t.Name, ix);
}
public void RemoveThread(string name)
{
// Find event from name and remove it from the pool to allocate empty slot
Thread t = this._threads.FirstOrDefault(x => x.Name == name);
if (t != null)
this._threads.Remove(t);
}
}
}
namespace TPConsoleTest
{
public class MyWorker
{
public void DoWork(string threadName, int ix)
{
// Dispatch a message signalling process start
Console.WriteLine("Thread {0} started for : #{1}", threadName, ix);
Random rnd = new Random();
int delay = rnd.Next(5);
delay++;
// Wait up to 5 second for each process. It may shorter or longer depending to a random value
Thread.Sleep(delay * 1000);
}
}
}
And I get the following results:
The problems are :
Thread.Sleep(delay * 1000);
does not seem to work. Everything happens in lightning speed.How can I fix these errors?
Upvotes: 0
Views: 552
Reputation: 28272
You are calling OnThreadDone
immediately after creating the thread, without waiting for it to complete:
t.Start();
this._threads.Add(t);
// The event is fired without waiting for the thread to end
if (OnThreadDone != null)
OnThreadDone(t.Name, ix);
You are supposed to call it when the worker method on your thread ends, not right after starting the thread
Upvotes: 2