相当于并行中的do() while{}
本文关键字:while do 并行 相当于 | 更新日期: 2023-09-27 18:08:20
如何在下面的Update()
方法中创建do
- while
或类似的并行等价物?
应用程序中的另一个线程随机写入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();
});
}
}
你可以通过'prepending'一个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);
}
});
for
/foreach
通常用于在多个项目上执行任务。
while
-do/do
- while
for:
。在多个项目上执行任务尚未被枚举的对象(如树)。
在这种情况下,你可以定义一个BFS或DFS枚举数,并在foreach中使用。
b。在单个项目上执行迭代工作
-迭代工作不适合并行
不要试图将代码从串行重构为并行。相反,考虑一下你的任务是什么,以及如何最好地并行完成它。(重构算法,而不是代码)
public static void While(
ParallelOptions parallelOptions, Func<bool> condition,
Action<ParallelLoopState> body)
{
Parallel.ForEach(Infinite(), parallelOptions, (ignored, loopState) =>
{
if (condition()) body(loopState);
else loopState.Stop();
});
}
private static IEnumerable<bool> Infinite()
{
while (true) yield return true;
}