2017-04-19 93 views
1

我希望只使用2個線程,使for循環的數量限制。我想這樣的代碼:C#TPL for循環 - 線程

ParallelOptions po = new ParallelOptions { 
    MaxDegreeOfParallelism = 2 
}; 

Parallel.For(0, width, po, x => { 
    sb.Append(Thread.CurrentThread.ManagedThreadId); 
    sb.Append(Environment.NewLine); 
    for (int y = 0; y < height; y++) { 
     double a = (double)(x - (width/2))/(double)(width/4); 
     double b = (double)(y - (height/2))/(double)(height/4); 
    } 
}); 

但是,當我顯示Thread.CurrentThread.ManagedThreadId,它會創建2組以上的ID。我也嘗試在循環之前添加此代碼:

ThreadPool.SetMaxThreads(2, 2); 
ThreadPool.SetMinThreads(2, 2); 

但它也不會改變任何東西。有人可能有任何想法如何解決這個問題?

+0

我希望你不使用StringBuilder的' '在多線程環境中,因爲它不是線程安全的 – MickyD

+0

我只用這個來創建所有線程ID的大字符串。你認爲,這個StringBuilder會造成運行多於2個線程的問題嗎? –

+0

是的。只要使用'Console.WriteLine(Environment.CurrentManagedThreadId)'或'Trace.TraceInformation .....' – MickyD

回答

2

MaxDegreeOfParallelism設置將同時使用Parallel.For()的線程的最大數量。這並不意味着只有兩個線程會被使用。

不同的線程可以從線程池的Parallel.For()的執行期間被分配,因爲線程池線程被特別設計成可重複使用。

下面的程序演示。如果你運行它,你會看到正在使用不同的線程總數可以超過2,但正在使用的線程總數同時不超過2

using System; 
using System.Collections.Concurrent; 
using System.Threading; 
using System.Threading.Tasks; 

namespace ConsoleApp1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      ParallelOptions po = new ParallelOptions 
      { 
       MaxDegreeOfParallelism = 2 
      }; 

      var activeThreads = new ConcurrentDictionary<int, bool>(); 

      Parallel.For(0, 100, po, x => 
      { 
       activeThreads[Thread.CurrentThread.ManagedThreadId] = true; 
       Console.WriteLine("Active threads: " + string.Join(", ", activeThreads.Keys)); 
       Thread.Sleep(200); 
       activeThreads.TryRemove(Thread.CurrentThread.ManagedThreadId, out bool unused); 
      }); 

      Console.ReadLine(); 
     } 
    } 
}