Первый цикл Parallel.ForEach
Я хотел бы запустить некоторый код внутри первого цикла Parallel.ForEach. Только в первом цикле. Причина состоит в том, чтобы записать некоторые диагностические данные на диск, которые создаются кодом внутри цикла. После первого цикла данные будут сохранены только в памяти и агрегированы позже. Будет ли это работать?
bool firstLoop = true;
Parallel.ForEach(someList,
p=>
{
// do something here
if (firstLoop)
{
firstLoop = false;
// do something here for the first loop
}
});
2 ответа
Если вам нужно, чтобы что-то произошло с первым элементом, а остальные итерации не зависят от того, что делается, вы можете использовать следующее, чтобы увидеть, обрабатываете ли вы первый элемент
if (p==items.First())
{
//Do something
}
Если вам нужно сделать что-то один раз, на что будут опираться остальные циклы, тогда вы можете использовать блокировку, как это было предложено Дэвидом, или вы можете делать то, что вам нужно, перед Parallel.ForEach.
Так что вы могли бы сделать
//Do stuff using someList(0)
Parallel.ForEach(someList.Skip(1), p=>
Как упомянуто в моем комментарии, это не будет гарантированно работать. Одним из вариантов будет создание блокировки и только оценка и обновление firstLoop
внутри замка Однако это может привести к потере части параллелизма и предложит вам поискать лучший подход, если только у вас нет насущных потребностей во время, необходимое для завершения операции.
Имейте в виду, что это не гарантирует, что firstLoop
будет оцениваться по первому элементу в вашем списке, только то, что он будет оценен как истинный только один раз.
var someList = new List<string>();
var obj = new object();
for (int i = 0; i < 1000; i++)
{
someList.Add(i.ToString());
}
bool firstLoop = true;
var rand = new Random(Guid.NewGuid().GetHashCode());
Parallel.ForEach(someList,
p =>
{
// do something here
var next = rand.Next(1, 100);
Thread.Sleep(next);
lock (obj)
{
if (firstLoop)
{
firstLoop = false;
firstLoop.Dump();
// do something here for the first loop
}
}
});