温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c# - Equivalent of do() while{} in Parallel
c# parallel-processing plinq

c# - 并行执行do()while {}

发布于 2020-03-27 11:34:26

如何在以下方法中创建do- while或类似物的平行等效物Update()

应用程序中的另一个线程TestBuffer随机写入TestBuffer.RemoveItemAndDoSomethingWithIt();应该运行到为止TestBuffer为空。当前Update()仅使用枚举时集合中的项目运行,这是有道理的。

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

internal class Tester
{
    private UnOrderedBuffer<Data> TestBuffer;

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

查看更多

查看更多

提问者
Canacourse
被浏览
105
1,064 2020-03-19 01:23

您可以通过在'prep'前添加一个null /默认值来强制执行一次:

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);
    }
});