2016-07-04 18 views
0

我是一個C#程序員,我遇到了一些線程問題。c#多樣化線程

資產是實體的,我需要運行的每個平行的資產,並運行的方法「doSomethingOnAsset」

我有一個有100個線程的程序(即每資產我做一些關於它的操作1線) 。通常,每個線程在運行的每個內部元素上都有相同的時間框架,並且每個線程都調用「doSomethingOnAsset」方法。

每個線程間隔運行10毫秒(即)。

我不想要那麼多的線程,所以我爲每個資產創建了一個隊列,但是在調用中心方法「doSomethingOnAsset」時 - 線程沒有以相同的時間間隔運行。

即第一個線程運行間隔週期爲300毫秒。 第二個線程運行間隔週期爲700毫秒。 第三個線程運行間隔週期爲2秒。 ...

什麼是運行一個預定義的方法並行的100倍的最佳方式(並行條目可能是外部服務,在運行時,觸發運行我的「doSomethingOnAsset」的代碼的事件。

public void doSomethingOnAsset(object obj) 
{ 
    // infinite loop when thread. 
    while (true) 
    { 
     doSomething(obj); 
     Thread.Sleep(100); 
    } 
} 

public void doSomething(object obj) 
{ 
    // do something. 
} 

public void Run() 
{ 
    Thread t;    
    for (int i = 0; i < 100; i++) 
    { 
     t = new Thread(new ParameterizedThreadStart(this.doSomethingOnAsset)); 
     t.Start(new object()); 
    } 

    Console.ReadLine(); 
} 

或致電事件信號,DoSomething的,當外部程序觸發。

謝謝:)

+2

邊注。爲什麼不'Parallel.For(...)'?明確創建'100'線程並不是一個好設計。例如:'Parallel.For(0,100,i => doSomethingOnAsset(i));' –

+0

既可以使用'Parallel.For'或者使用線程池或任務對它們進行排隊,則應該自動處理並行性。 –

+2

你有100個核心嗎?這聽起來不像是一個優化吞吐量的好計劃。 – spender

回答

1

對於這些類型的生產,消費情況,我通常定義阻塞收集,定義和創建一個consu mer(或多個),並開始向集合添加數據。每個消費者實例都會嘗試購買一個項目,如果有的話,會消耗它。否則,它會等待一個項目。

您可以添加取消令牌以支持停止處理。

您可以通過添加更多消費者來輕鬆擴展它。當然,最有效的數字取決於機器和核心數量,以及每個項目的處理長度。

消費者:

public class MyConsumer<T> { 
    public MyConsumer(BlockingCollection<T> collection, Action<T> action) { 
     _collection = collection; 
     _action = action; 
    } 

    private readonly BlockingCollection<T> _collection; 
    private readonly Action<T> _action; 

    public void StartConsuming() { 
     new Task(Consume).Start(); 
    } 

    private void Consume() { 
     while (true) { 
      var obj = _collection.Take(); 
      _action(obj); 
     } 
    } 
} 

用法:

public void doSomething(object obj) { 
    // do something. 
} 

public void Run() { 
    var collection = new BlockingCollection<object>(); 

    // Start workers 
    for (int i = 0; i < 5; i++) { 
     new MyConsumer<object>(collection, doSomethingOnAsset); 
    } 

    // Create object to consume 
    for (int i = 0; i < 100; i++) { 
     collection.Add(new object()); 
    } 
} 
+0

不需要使用冷任務,即Task(Consume).Start(),Task.Run會做。此外,需要*阻止*任務/線程等待輸入。框架的ActionBlock已經做到了這一點,沒有阻塞和更好地控制緩衝,DOP –