Given the following code, how does the count++ behave under concurrent access in c#:
int count = 0;int Count=0;
ActionBlock<Tuple<CloudBlockBlob, CloudBlockBlob>> copyblock =
new ActionBlock<Tuple<CloudBlockBlob, CloudBlockBlob>>(async (tuple) =>
{
await tuple.Item2.StartCopyFromBlobAsync(tuple.Item1);
var progessDone = count++ / (double)Count;
progress(progessDone,tuple.Item2.Name);
},
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = ExecutionDataflowBlockOptions.Unbounded });
1) Is it possible that two tasks can update count at the same time such both reads and then both writes ending up with only counting up by one? 2) If so, what is best practice to avoid that? a lock around it?
Yes, that's entirely possible - at the very least theoretically - but no, you don't need a lock. Just use Interlocked.Increment
:
var progressDone = Interlocked.Increment(ref count) / (double) Count;
(It's possible that depending on your CPU architecture and the JIT, the increment may end up being atomic anyway, but it's definitely not guaranteed. Even with atomicity, there's the possibility of one thread not seeing the value written by another without memory barriers. Interlocked.Increment
fixes all of this, and was precisely designed for this sort of situation.)
See more on this question at Stackoverflow