Reputation: 829
I would like to run some code inside the first loop of a Parallel.ForEach. Only in the first loop whichever it is. The reason is to write some diagnostic data to disk that is produced by the code inside the loop. After the first loop data will be only kept in the memory and aggregated later. Would this work?
bool firstLoop = true;
Parallel.ForEach(someList,
p=>
{
// do something here
if (firstLoop)
{
firstLoop = false;
// do something here for the first loop
}
});
Upvotes: 1
Views: 1133
Reputation: 993
If you need something to happen on the first item, and the rest of the iterations don't rely on what's being done, you can use the following to see if you're processing the first item
if (p==items.First())
{
//Do something
}
If you need to do something once that the rest of the loops will rely on then you can use a lock as suggested by David or you can do what you need before the Parallel.ForEach
So you could do
//Do stuff using someList(0)
Parallel.ForEach(someList.Skip(1), p=>
Upvotes: 2
Reputation: 33815
As mentioned in my comment, this will not be at all guaranteed to work. One option would be to create a lock and only evaluate and update firstLoop
inside the lock. However, this would cause you to lose a some of your parallelism and would suggest that you look for a better approach, unless you do not have pressing needs around the time that it takes to complete the operation.
Keep in mind that this does not guarantee that firstLoop
will be evaluated on the first item in your list, only that it will only be evaluated to true once.
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
}
}
});
Upvotes: 1