Can*_*rse 8 c# parallel-processing plinq
如何在下面的方法中创建与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();
});
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过“前置”空/默认值来强制执行一次:
static IEnumerable<T> YieldOneDefault<T>(this IEnumerable<T> values)
{
yield return default(T);
foreach(var item in values)
yield return item;
}
Run Code Online (Sandbox Code Playgroud)
然后使用它如下:
Parallel.ForEach(TestBuffer.YieldOneDefault(), Item =>
{
if(Item != null)
TestBuffer.RemoveItemAndDoSomethingWithIt();
else
DoSomethingDuringTheFirstPass();
});
Run Code Online (Sandbox Code Playgroud)
尽管我怀疑您可能正在寻找以下扩展方法:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这会让你得到这个结果(我认为这就是你想要的):
Parallel.ForEach(TestBuffer.GetParrallelConsumingEnumerable(), Items =>
{
foreach(var item in Items)
{
DoSomethingWithItem(item);
}
});
Run Code Online (Sandbox Code Playgroud)
for/foreach通常用于对多个项目执行任务。
while-do/ do-while用于:
A。对尚未枚举的多个项目(例如树)执行任务。
- 在这种情况下,您可以定义 BFS 或 DFS 枚举器并在 foreach 中使用。
b. 对单个项目执行迭代工作
- 迭代工作不适合并行性
不要尝试将代码从串行重构为并行。相反,请考虑您的任务是什么以及如何最好地并行完成它。(重构算法,而不是代码。)
| 归档时间: |
|
| 查看次数: |
13809 次 |
| 最近记录: |