2012-06-21 85 views
2

這段代碼有什麼問題,或者這可以更有效地完成嗎?特別是,我有點擔心parrallel.foreach發射/調用委託內的代碼。這可能會導致任何問題? 我問,因爲目前消費者無法跟上正在生產的物品在很多情況下,導致內存問題。Parallel.Foreach委託調用另一個委託

public delegate void DataChangedDelegate(DataItem obj); 

public class Consumer 
{ 
    public DataChangedDelegate OnCustomerChanged; 
    public DataChangedDelegate OnOrdersChanged; 

    private CancellationTokenSource cts; 
    private CancellationToken ct; 
    private BlockingCollection<DataItem> queue; 

    public Consumer(BlockingCollection<DataItem> queue) { 
     this.queue = queue; 
     Start(); 
    } 

    private void Start() { 
     cts = new CancellationTokenSource(); 
     ct = cts.Token; 
     Task.Factory.StartNew(() => DoWork(), ct); 
    } 

    private void DoWork() { 

     Parallel.ForEach(queue.GetConsumingPartitioner(), item => { 
      if (item.DataType == DataTypes.Customer) { 
       OnCustomerChanged(item); 
      } else if(item.DataType == DataTypes.Order) { 
       OnOrdersChanged(item); 
      } 
     }); 
    } 
} 
+0

是否有多個消費者實例創建?如果是,爲什麼不只有一個靜態實例處理隊列? –

+0

沒有一個實例... – mike01010

回答

2

特別是,我有點擔心/ parrallel.foreach燒製中的代碼調用的委託。這可能會導致任何問題?

一般而言,從Parallel.ForEach方法中調用委託沒有任何問題。

但是,它確實使控制線程安全性變得更加困難,因爲委託將承擔正確處理所有數據同步的要求。這主要是一個問題,因爲使用委託的主要原因是允許您調用的「方法」被傳入,這意味着它是從外部提供的。

這意味着,例如,如果委託人碰巧調用試圖更新用戶界面的代碼,則可能會遇到麻煩,因爲它將從後臺/ ThreadPool線程調用。

+0

謝謝。期望上面的消費者無限期地處理被循環加入的隊列是不合理的(沒有延遲......即真的非常快)?我基本上試圖測試消費者是否能夠跟上這種(罕見)的情況。到目前爲止,他們不能,並最終耗盡內存。 – mike01010

+0

@ mike01010非常多 - 除非你有多個消費者。分區/調度開銷永遠不會匹配您在固定循環中添加項目的速度......所以您最終會落後。你需要對添加進行一些限制,或者對多個消費者進行處理...... –

+0

即時消息不確定這會有所幫助..沒有並行.foreach假設嘗試根據需要產生線程(有效地做同樣的事情,多個消費者會)? – mike01010