Parallel.ForEach:中断并ParallelLoopState.LowestBreakIteration。怎么办?
Parallel.ForEach: Break and ParallelLoopState.LowestBreakIteration. What to do about it?
In this article on docs microsoft,在方法中的例子Parallel.For中,有一个Break调用和对ShouldExitCurrentIteration和LowestBreakIteration等属性的处理如下:
if (state.ShouldExitCurrentIteration)
{
if (state.LowestBreakIteration < i)
return;
}
LowestBreakIteration 存储调用 Break 方法的最小迭代次数。
此外,此 属性 可以存储内部生成的索引的值,例如在方法 Parallel.ForEach (source on docs microsoft)
的情况下
问题。 属性 LowestBreakIteration 在Parallel.ForEach 的情况下应该如何处理,我应该如何使用它,我应该与什么进行比较?
我很容易地用 Break for Parallel.For 重复了这个例子,但是我不知道如何在 Break for Parallel.ForEach 的例子中使用 属性 LowestBreakIteration。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//Parallel.For
void MyMethodForParallelForBreak(int i, ParallelLoopState MyParallelLoopState)
{
Console.WriteLine($"Start {i}");
if (MyParallelLoopState.ShouldExitCurrentIteration)
{
if (MyParallelLoopState.LowestBreakIteration < i) //Processing LowestBreakIteration here
{
Console.WriteLine($"Current {i}. Return: LowestBreakIteration {MyParallelLoopState.LowestBreakIteration} < {i}");
return;
}
}
if (MyParallelLoopState.LowestBreakIteration != null)
{
Console.WriteLine($"Current {i}. LowestBreakIteration {MyParallelLoopState.LowestBreakIteration}");
}
if (i > 5)
{
MyParallelLoopState.Break();
Console.WriteLine($"Current {i}. Break");
}
Console.WriteLine($"End {i}");
}
Parallel.For(1, 11, MyMethodForParallelForBreak);
Console.WriteLine("\n");
//Parallel.ForEach
void MyMethodForParallelForEachBreak(KeyValuePair<string, string> MyKeyValuePair, ParallelLoopState MyParallelLoopState)
{
Console.WriteLine($"Start {MyKeyValuePair.Key}");
if (MyParallelLoopState.ShouldExitCurrentIteration)
{
if (MyParallelLoopState.LowestBreakIteration < ) //Error. Unknown. Processing LowestBreakIteration here
{
Console.WriteLine($"Current {MyKeyValuePair.Key}. Return: LowestBreakIteration {MyParallelLoopState.LowestBreakIteration} < Unknown");
return;
}
}
if (MyParallelLoopState.LowestBreakIteration != null)
{
Console.WriteLine($"Current {MyKeyValuePair.Key}. LowestBreakIteration {MyParallelLoopState.LowestBreakIteration}");
}
if (MyKeyValuePair.Value == "a")
{
MyParallelLoopState.Break();
Console.WriteLine($"Current {MyKeyValuePair.Key}. Break");
}
Console.WriteLine($"End {MyKeyValuePair.Key}");
}
Dictionary<string, string> MyDictionaryForStringAndString = new Dictionary<string, string>();
MyDictionaryForStringAndString.Add("a1", "abc");
MyDictionaryForStringAndString.Add("a2", "ab");
MyDictionaryForStringAndString.Add("a3", "a");
MyDictionaryForStringAndString.Add("a4", "abc");
MyDictionaryForStringAndString.Add("a5", "ab");
MyDictionaryForStringAndString.Add("a6", "a");
MyDictionaryForStringAndString.Add("a7", "abc");
MyDictionaryForStringAndString.Add("a8", "ab");
MyDictionaryForStringAndString.Add("a9", "a");
MyDictionaryForStringAndString.Add("a10", "abc");
Parallel.ForEach(MyDictionaryForStringAndString, MyMethodForParallelForEachBreak);
}
}
}
您可以检查ShouldExitCurrentIteration
属性 以查看是否需要退出并行foreach:
if (state.ShouldExitCurrentIteration) {
// some other thread called state.Break()
return;
}
如果您想在 Parallel.Foreach
循环中检查 LowestBreakIteration,可以使用带有 Action<TSource, ParallelLoopState, long>
参数的 overload。其中 long-value 代表索引。
我会注意到 LowestBreakIteration / ShouldExitCurrentIteration 的用法对我来说似乎非常深奥。我能想象的唯一用例是每次迭代都涉及多个昂贵的操作,所以你想尽快退出, 和 你仍然想在调用的迭代之前处理所有项目休息。
我肯定从来没有觉得需要这样的功能,虽然对于那些确实需要它的人来说可能很好,但我不会担心它。
In this article on docs microsoft,在方法中的例子Parallel.For中,有一个Break调用和对ShouldExitCurrentIteration和LowestBreakIteration等属性的处理如下:
if (state.ShouldExitCurrentIteration)
{
if (state.LowestBreakIteration < i)
return;
}
LowestBreakIteration 存储调用 Break 方法的最小迭代次数。 此外,此 属性 可以存储内部生成的索引的值,例如在方法 Parallel.ForEach (source on docs microsoft)
的情况下问题。 属性 LowestBreakIteration 在Parallel.ForEach 的情况下应该如何处理,我应该如何使用它,我应该与什么进行比较?
我很容易地用 Break for Parallel.For 重复了这个例子,但是我不知道如何在 Break for Parallel.ForEach 的例子中使用 属性 LowestBreakIteration。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//Parallel.For
void MyMethodForParallelForBreak(int i, ParallelLoopState MyParallelLoopState)
{
Console.WriteLine($"Start {i}");
if (MyParallelLoopState.ShouldExitCurrentIteration)
{
if (MyParallelLoopState.LowestBreakIteration < i) //Processing LowestBreakIteration here
{
Console.WriteLine($"Current {i}. Return: LowestBreakIteration {MyParallelLoopState.LowestBreakIteration} < {i}");
return;
}
}
if (MyParallelLoopState.LowestBreakIteration != null)
{
Console.WriteLine($"Current {i}. LowestBreakIteration {MyParallelLoopState.LowestBreakIteration}");
}
if (i > 5)
{
MyParallelLoopState.Break();
Console.WriteLine($"Current {i}. Break");
}
Console.WriteLine($"End {i}");
}
Parallel.For(1, 11, MyMethodForParallelForBreak);
Console.WriteLine("\n");
//Parallel.ForEach
void MyMethodForParallelForEachBreak(KeyValuePair<string, string> MyKeyValuePair, ParallelLoopState MyParallelLoopState)
{
Console.WriteLine($"Start {MyKeyValuePair.Key}");
if (MyParallelLoopState.ShouldExitCurrentIteration)
{
if (MyParallelLoopState.LowestBreakIteration < ) //Error. Unknown. Processing LowestBreakIteration here
{
Console.WriteLine($"Current {MyKeyValuePair.Key}. Return: LowestBreakIteration {MyParallelLoopState.LowestBreakIteration} < Unknown");
return;
}
}
if (MyParallelLoopState.LowestBreakIteration != null)
{
Console.WriteLine($"Current {MyKeyValuePair.Key}. LowestBreakIteration {MyParallelLoopState.LowestBreakIteration}");
}
if (MyKeyValuePair.Value == "a")
{
MyParallelLoopState.Break();
Console.WriteLine($"Current {MyKeyValuePair.Key}. Break");
}
Console.WriteLine($"End {MyKeyValuePair.Key}");
}
Dictionary<string, string> MyDictionaryForStringAndString = new Dictionary<string, string>();
MyDictionaryForStringAndString.Add("a1", "abc");
MyDictionaryForStringAndString.Add("a2", "ab");
MyDictionaryForStringAndString.Add("a3", "a");
MyDictionaryForStringAndString.Add("a4", "abc");
MyDictionaryForStringAndString.Add("a5", "ab");
MyDictionaryForStringAndString.Add("a6", "a");
MyDictionaryForStringAndString.Add("a7", "abc");
MyDictionaryForStringAndString.Add("a8", "ab");
MyDictionaryForStringAndString.Add("a9", "a");
MyDictionaryForStringAndString.Add("a10", "abc");
Parallel.ForEach(MyDictionaryForStringAndString, MyMethodForParallelForEachBreak);
}
}
}
您可以检查ShouldExitCurrentIteration
属性 以查看是否需要退出并行foreach:
if (state.ShouldExitCurrentIteration) {
// some other thread called state.Break()
return;
}
如果您想在 Parallel.Foreach
循环中检查 LowestBreakIteration,可以使用带有 Action<TSource, ParallelLoopState, long>
参数的 overload。其中 long-value 代表索引。
我会注意到 LowestBreakIteration / ShouldExitCurrentIteration 的用法对我来说似乎非常深奥。我能想象的唯一用例是每次迭代都涉及多个昂贵的操作,所以你想尽快退出, 和 你仍然想在调用的迭代之前处理所有项目休息。
我肯定从来没有觉得需要这样的功能,虽然对于那些确实需要它的人来说可能很好,但我不会担心它。