2011-09-13 66 views
2

在下面的Update()方法中,我如何獲得代碼的並行等價操作。do()while while {}}的等價

應用中的另一個線程隨機寫入Testbuffer。應該運行TestBuffer.RemoveItemAndDoSomethingWithIt();,直到Testbuffer爲空。當前Update()只與列​​舉枚舉集合時的項目一起運行。這是有道理的......

namespace Test 
{ 
    internal class UnOrderedBuffer<T> where T : class 
    { 
    ConcurrentBag<T> GenericBag = new ConcurrentBag<T>(); 
    } 
} 


namespace Test 
{ 
    internal class Tester 
    { 
    private UnOrderedBuffer<Data> TestBuffer; 

    public void Update() 
    { 
     Parallel.ForEach(TestBuffer, Item => 
     { 
     TestBuffer.RemoveItemAndDoSomethingWithIt(); 
     }); 
    } 
    } 
} 
+0

你是什麼用意?你想要多線程來處理TestBuffer,還是想在後臺線程中異步處理TestBuffer? –

+0

使用可用內核儘快清空TestBuffer。 – Canacourse

回答

2

你可以通過強制 '預謀' 空/默認值一次執行:

static IEnumerable<T> YieldOneDefault<T>(this IEnumerable<T> values) 
{ 
    yield return default(T); 
    foreach(var item in values) 
     yield return item; 
} 

然後按如下方式使用它:

Parallel.ForEach(TestBuffer.YieldOneDefault(), Item => 
     { 
      if(Item != null) 
       TestBuffer.RemoveItemAndDoSomethingWithIt(); 
      else 
       DoSomethingDuringTheFirstPass(); 
     }); 

雖然我懷疑你可能正在尋找以下擴展方法:

public static IEnumerable<IEnumerable<T>> GetParrallelConsumingEnumerable<T>(this IProducerConsumerCollection<T> collection) 
{ 
    T item; 
    while (collection.TryTake(out item)) 
    { 
     yield return GetParrallelConsumingEnumerableInner(collection, item); 
    } 
} 

private static IEnumerable<T> GetParrallelConsumingEnumerableInner<T>(IProducerConsumerCollection<T> collection, T item) 
{ 
    yield return item; 
    while (collection.TryTake(out item)) 
    { 
     yield return item; 
    } 
} 

,這將讓你得到這個結果(我認爲這是你所追求的):

Parallel.ForEach(TestBuffer.GetParrallelConsumingEnumerable(), Items =>  
     { 
      foreach(var item in Items) 
      { 
       DoSomethingWithItem(item); 
      } 
     }); 
+0

正如我所理解的問題,OP尋找的答案是您寫的第一個擴展方法。 – Motti

+0

@Jonathan Dickinson嘗試了兩個建議,並在兩者上都得到了「錯誤\t 1擴展方法必須在非泛型靜態類中定義」。 – Canacourse

+0

@Canacourse - 錯誤是什麼意思?提示:它告訴你如何定義擴展方法。 –

3
 
For/Foreach are usually used for performing a task on multiple items. 

While-Do/Do-while are for: 

a. Performing a task on multiple items 
that have not yet been enumerated (e.g. a tree). 
- In this case you can define a BFS or DFS enumerator and use in a foreach. 

b. Performing iterative work on a single item 
- Iterative work is not suitable for parallelism 

Do not attempt to refactor code from serial to parallel. 
Instead, consider what you assignment is and how it is best done in parallel. 
(Refactor algorithm, not code.) 
+0

公平點。學過的知識.. – Canacourse