2015-03-28 3 views
1

Первый таймер для Threadpooling и критических разделов. Я пытаюсь управлять количеством потоков, которые активны в любой момент времени. Класс MyThreadPool управляет количеством потоков и активными потоками. MyUsefulWork имеет квадратный метод, к которому обращаются потоки. Основной метод останавливает работу с помощью ThreadPool.QueueUserWorkItem.C# Управляемый пул потоков. Больше потоков работает одновременно, чем ожидалось

Я использую методы класса ManualResetEvent Set() и WaitOne(), чтобы попытаться ограничить потоки максимальным количеством (MyThreadPool.MaxThreads), которое в этом примере равно трем. Но, видимо, я делаю что-то неправильно, учитывая, что мой счет ActiveThreads выходит за пределы MaxThreads до 18 (который отображается на выходе как «Increment: number» или «Decrement: number»). Кроме того, activethreads увеличивается в пределах блокировки, так что если поток ожидает, активный поток не увеличивается.

Итак, если кто-нибудь может указать, что я делаю неправильно, это было бы очень полезно. Спасибо.

using System; 
using System.Collections.Generic; 
using System.Threading; 

namespace ThreadingDemo 
{ 
    class MyUsefulWork 
    { 
     public void Square(object number) 
     { 
      try 
      { 
       Console.WriteLine("Thread: {0} Square of {1} is {2}", Thread.CurrentThread.GetHashCode(), number, Math.Pow(Convert.ToDouble(number), 2)); 
       Thread.Sleep(2000); 
       Console.WriteLine("Thread for {0} woke up", number); 
      } 
      catch { } 
      finally 
      { 
       MyThreadPool.ThreadFinishedWork(); 
      } 
     } 
    } 

    public static class MyThreadPool 
    { 
     private static int ActiveThreads { get; set; } 
     private static int MaxThreads { get; set; } 
     public static ManualResetEvent Mre { get; set; } 
     public static Object IncrementLock { get; set; } 
     public static Object DecreementLock { get; set; } 

     public static void SetMaxThreads(int maxThreads) 
     { 
      MaxThreads = maxThreads; 
     } 
     public static int GetMaxThreads() 
     { 
      return MaxThreads; 
     } 
     public static void ThreadStartedWork() 
     { 
      SetWait(); 
     } 
     public static void ThreadFinishedWork() 
     { 
      ActiveThreads--; 
      ReleaseWait(); 
     } 
     private static void SetWait() 
     { 
      lock (IncrementLock) 
      { 
       ActiveThreads++; 
       Console.WriteLine("Increment: {0}", ActiveThreads); 
       if (ActiveThreads >= MaxThreads) 
        Mre.WaitOne(Timeout.Infinite, true); 
      } 
     } 
     private static void ReleaseWait() 
     { 
      lock (DecreementLock) 
      { 
       Console.WriteLine("Decreement: {0}", ActiveThreads); 
       if (ActiveThreads < MaxThreads) 
        Mre.Set(); 
      } 
     } 
    } 

    class Program 
    { 
     public static int Main(string[] args) 
     { 
      var myUsefulWork = new MyUsefulWork(); 
      var inputs = new List<string>(); 

      MyThreadPool.Mre = new ManualResetEvent(false); 
      MyThreadPool.IncrementLock = new object(); 
      MyThreadPool.DecreementLock = new object(); 
      MyThreadPool.SetMaxThreads(3); 

      for (var i = 1; i <= 20; i++) 
       inputs.Add(i.ToString()); 

      for (int iItem = 1; iItem <= 20; iItem++) 
      { 
       Console.WriteLine("Queue to Thread Pool {0}", iItem); 
       MyThreadPool.ThreadStartedWork(); 
       ThreadPool.QueueUserWorkItem(new WaitCallback(myUsefulWork.Square), iItem.ToString()); 
      } 
      Console.ReadKey(); 
      return 0; 
     } 
    }  
} 

Выход следующий.

Queue to Thread Pool 1 
Increment: 1 
Queue to Thread Pool 2 
Increment: 2 
Queue to Thread Pool 3 
Increment: 3 
Thread: 6 Square of 1 is 1 
Thread: 11 Square of 2 is 4 
Thread for 1 woke up 
Decreement: 2 
Queue to Thread Pool 4 
Increment: 3 
Thread: 12 Square of 3 is 9 
Queue to Thread Pool 5 
Increment: 4 
Queue to Thread Pool 6 
Increment: 5 
Queue to Thread Pool 7 
Increment: 6 
Queue to Thread Pool 8 
Increment: 7 
Thread: 6 Square of 4 is 16 
Queue to Thread Pool 9 
Increment: 8 
Queue to Thread Pool 10 
Increment: 9 
Queue to Thread Pool 11 
Increment: 10 
Queue to Thread Pool 12 
Increment: 11 
Queue to Thread Pool 13 
Increment: 12 
Queue to Thread Pool 14 
Increment: 13 
Thread for 2 woke up 
Decreement: 12 
Thread: 11 Square of 5 is 25 
Queue to Thread Pool 15 
Increment: 13 
Queue to Thread Pool 16 
Increment: 14 
Queue to Thread Pool 17 
Increment: 15 
Queue to Thread Pool 18 
Increment: 16 
Queue to Thread Pool 19 
Increment: 17 
Queue to Thread Pool 20 
Increment: 18 
Thread: 13 Square of 6 is 36 
Thread: 14 Square of 7 is 49 
Thread for 3 woke up 
Decreement: 17 
Thread for 4 woke up 
Decreement: 16 
Thread: 6 Square of 9 is 81 
Thread: 12 Square of 8 is 64 
Thread for 5 woke up 
Decreement: 15 
Thread: 11 Square of 10 is 100 
Thread: 15 Square of 11 is 121 
Thread for 6 woke up 
Decreement: 14 
Thread: 13 Square of 12 is 144 
Thread for 7 woke up 
Decreement: 13 
Thread: 14 Square of 13 is 169 
Thread for 9 woke up 
Decreement: 12 
Thread: 6 Square of 14 is 196 
Thread for 8 woke up 
Decreement: 11 
Thread: 12 Square of 15 is 225 
Thread for 10 woke up 
Decreement: 10 
Thread: 11 Square of 16 is 256 
Thread for 11 woke up 
Decreement: 9 
Thread: 15 Square of 17 is 289 
Thread for 12 woke up 
Decreement: 8 
Thread: 13 Square of 18 is 324 
Thread for 13 woke up 
Decreement: 7 
Thread: 14 Square of 19 is 361 
Thread for 14 woke up 
Decreement: 6 
Thread: 6 Square of 20 is 400 
Thread for 15 woke up 
Decreement: 5 
Thread for 16 woke up 
Decreement: 4 
Thread for 17 woke up 
Decreement: 3 
Thread for 18 woke up 
Decreement: 2 
Thread for 19 woke up 
Decreement: 1 
Thread for 20 woke up 
Decreement: 0 

ответ

2

Вы забыли Reset()ManualResetEvent, он всегда остается множество.

Вы, вероятно, хотите использовать AutoResetEvent вместо ManualResetEvent см here

+1

Спасибо Thumbmunkeys. AutoResetEvent работает как очарование. Вероятно, вы сохранили мое воскресенье;) – Pazza22

Смежные вопросы