2013-01-08 56 views
5

在這個例子中,如果我想限制可以執行函數DoWork的線程數一次爲10,那麼這是否正確使用了Parallel.For循環?其他線程是否會被阻塞,直到十個線程中的一個變爲可用?如果不是,什麼是更好的多線程解決方案,仍然可以讓我執行6000+次以上的功能?在C#中正確使用Parallel for循環?

class Program 
{ 
    static void Main(string[] args) 
    { 
     ThreadExample ex = new ThreadExample(); 
    } 
} 

public class ThreadExample 
{ 
    int limit = 6411; 

    public ThreadExample() 
    { 
     Console.WriteLine("Starting threads..."); 
     int temp = 0; 
     Parallel.For(temp, limit, new ParallelOptions { MaxDegreeOfParallelism = 10 }, i => 
     { 
      DoWork(temp); 
      temp++; 
     }); 
    } 

    public void DoWork(int info) 
    { 
     //Thread.Sleep(50); //doing some work here. 

     int num = info * 5; 

     Console.WriteLine("Thread: {0}  Result: {1}", info.ToString(), num.ToString()); 
    } 
} 
+2

'temp ++'不是線程安全的。 – SLaks

+0

@SLaks是的,它不是線程安全的,但在本次比賽中有意義嗎?如何工作Parallel.For? –

+1

@HamletHakobyan你是什麼意思?程序員的意圖是清楚的;他想要統計已完成任務的數量。實際發生的事情並不是一回事,因爲競爭條件可能會導致計數器無法正確遞增。使用'interlocked.Exchange'就可以解決這個問題。至於'Paralle.For',它是一個'for'循環,迭代被多個線程並行執行(在一定程度上)。 – Servy

回答

15

您需要使用傳遞給lambda函數的i作爲索引。 Parallel.For可以使您免於使用循環計數器的麻煩,但您需要使用它!

Parallel.For(0, limit, new ParallelOptions { MaxDegreeOfParallelism = 10 }, i => 
    { 
     DoWork(i); 
    }); 

至於你的其他問題:

  • 是的,這將限制正確的線程同時工作的量。
  • 有沒有線程被阻止。迭代排隊,只要線程變得可用,就會從隊列中進行下一次迭代(以同步的方式)進行處理。
+0

MaxDegreeOfParallelism是你在尋找 –

+1

@MicahArmantrout他已經在OP中使用它;這並不是給他帶來麻煩的原因。這個答案正確地識別了OP代碼的問題。 – Servy

+0

這是OP解決方案的一個問題,但它沒有回答任何特定的問題(除了「這可以嗎?」)。 – usr