Reputation: 8307
I need to check if any iterations of a Parallel.ForEach
reach a specific point. From my understanding the following would be safe if my bool
was a volatile
field, but it needs to be a variable in the enclosing method:
bool anySuccess = false;
Parallel.ForEach(things, thing =>
{
// stuff happens...
anySuccess = true;
});
if(!anySuccess)
throw new Exception("No things succeeded :(");
Can I use this code as-is or should I use a lock
or Interlocked
function?
Upvotes: 4
Views: 2036
Reputation: 132
I would lock the bool. Also, I would suggest moving your if statement into the Parallel.Foreach block. Reason:
This will evaluate after the parallel loop, thus reading only the last update of anySuccess
bool anySuccess = false;
Parallel.ForEach(things, thing =>
{
// stuff happens...
anySuccess = true;
});
if(!anySuccess)
throw new Exception("No things succeeded :(");
This will evaluate all updates of the bool
Object myLock = new Object();
bool anySuccess = false;
Parallel.ForEach(things, thing =>
{
// stuff happens...
lock (myLock)
{
anySuccess = true;
}
if(!anySuccess)
throw new Exception("No things succeeded :(");
});
Upvotes: -2
Reputation: 8557
If that code is the ENTIRETY of the loops' access to that boolean, then yes that seems safe to me.
In general basic value types aren't thread safe in the sense that many of the operations performed on them aren't atomic.
But if the ONLY thing you're ever doing is assigning to that variable ... never reading it, never changing branch based on it, never writing to it based on it's current state ... and all the writes are the same (the ONLY modification that can happen is to set it to true
) then I don't see any way for the non-atomicity to cause a problem.
==ADDITION==
The above comments on the correctness of the current code. It is also worth considering the long-term safeness of the code in it's context as part of your codebase. Leaving that code as it is, is setting up a trap for a future developer who doesn't know/understand/recognise what is going on, and why it's CURRENTLY safe.
If you leave it like this, it will be essential to put a CLEAR comment on both the declaration and the single usage explaining what's going on, why it's safe, and why they musn't start reading/using the variable in other ways.
The alternative (adding locking code) is long-term safer, but likely to also be very slightly less performant.
Upvotes: 4