2017-05-26 70 views
0

我想写一个自定义线程池对象来运行可能需要很长一段时间了一定作用。编写自定义线程池

我写了下面的代码运行模拟:

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

我得到如下结果: enter image description here

的问题是:

  1. 命令模拟进程延迟Thread.Sleep(delay * 1000);似乎不起作用。一切都以闪电的速度发生。
  2. 你可以从消息看,线程甚至开始之前获得了一些线索结果。

我怎样才能解决这些错误?

+3

要调用'OnThreadDone'创建线程,而不必等待它完成之后。当线程上的工作者方法结束时,您应该调用它,而不是在启动线程后立即调用 – Jcl

+0

非常感谢@Jcl。我将尽快更新代码。 – user3021830

+0

非常感谢。这是答案。现在它可以工作。如果您将其写为帖子而不是评论,我会将其标记为答案。 – user3021830

回答

2

您所创建的线程后立即调用OnThreadDone,而不必等待它完成:启动线程

后不对

t.Start();  
this._threads.Add(t); 

// The event is fired without waiting for the thread to end 
if (OnThreadDone != null) 
    OnThreadDone(t.Name, ix); 

你应该在你的线程的辅助方法结束调用它,