private bool isProcessing=false;
public bool IsProcessing { get { return isProcessing; } }
private bool IsTerminated=false;
private bool isPaused=false;
public bool IsPaused { get { return isPaused; } }
此函数包含Parallel.ForEach
private void StartProcess()
{
isPaused = IsTerminated = false;
isProcessing = true;
Parallel.ForEach(items, new ParallelOptions() { MaxDegreeOfParallelism = 4 }, (item, state) =>
{
if (isPaused) state.Stop();
if (IsTerminated) state.Break();
item.Process();
});
isPaused = IsTerminated = false;
isProcessing = false;
}
考虑以下情况,调用StartProcess(),然后将IsTerminated设置为true,循环中断,当isPaused设置为true时同样发生,我不知道如何在调用Stop()后恢复Parallel.ForEach ,我怎么能得到每个线程已经开始和停止的位置的索引?
在暂停/恢复的情况下,我通过向项目对象添加一个布尔值来指示它是否被处理, 然后继续再次调用StartProcess()并跳过已处理的项目,但我确信有更好的方法,我不需要自定义我的对象结构,另一种方法是添加处理过的项目引用列表并在简历中跳过它们
答案 0 :(得分:1)
答案 1 :(得分:1)
您需要从ParallelLoopResult
电话中获取Parallel.ForEach
。它会告诉你哪个是最后处理的元素。
此外,您似乎向后Stop()
和Break()
。 Stop()
会尽快停止,您处理的最后一个项目下方的某些项目可能尚未处理。 Break()
会尽快停止,但会继续处理,直到处理完当前项目之前的所有项目,然后报告上次处理的项目的索引。
private long? lowestBreakIndex = null;
private void StartProcess()
{
isPaused = IsTerminated = false;
isProcessing = true;
ParallelLoopResult result = Parallel.ForEach(
items.Skip(lowestBreakIndex ?? 0) //I am assuming that items is some form of ICollection. The Skip function will skip to the next item to process
, new ParallelOptions() { MaxDegreeOfParallelism = 4 }, (item, state) =>
{
//I swapped these two.
if (isPaused)
state.Break();
else if (IsTerminated)
state.Stop();
else
item.Process();
});
lowestBreakIndex = result.LowestBreakIteration;
isPaused = IsTerminated = false;
isProcessing = false;
}
重要提示:您可能会运行两次相同的项目。请注意,如果两个线程都报告了中断,则两个线程中的较低者将是报告结果的人。
有关Stop()
和Break()
的详细信息,请参阅另一个有关Parallel.ForEach的问题的this old answer of mine。