I am looking for information regarding the thread-safety of concurrent writes to the System.Collections.BitArray class.
Specifically, consider the following contrived example:
BitArray bits = new BitArray(1000000);
Parallel.For(0, bits.Count, i =>
{
bits[i] = i % 3 == 0;
});
Instinct tells me that concurrent unlocked access would produce an incorrect result if two threads attempt to write to the same underlying integral value of the bitarray, yet I can not find any evidence to support it, and I have not encountered any problems during runtime.
Is this a safe operation?
If not, why am I not seeing this code fail or produce incorrect output?
Update
After further testing, I think the following test proves that using a BitArray in this example is not thread safe.
Using a bool[] on the other hand, does seem to be safe.
private static bool CompareBitArrays(BitArray a, BitArray b)
{
if (a.Count != b.Count) return false;
for (int i = 0; i < a.Count; i++)
{
if (a[i] != b[i]) return false;
}
return true;
}
static void Main(string[] args)
{
int numElements = 1000000;
//create single-threaded bitarray with certifiably correct values.
BitArray controlGroup = new BitArray(numElements);
for (int i = 0; i < numElements; i++)
{
controlGroup[i] = i % 3 == 0;
}
//create a BitArray and bool array of equal size and fill them using Parallel.For.
BitArray bits = new BitArray(numElements);
bool[] bools = new bool[numElements];
Parallel.For(0, numElements, i =>
{
bits[i] = bools[i] = i % 3 == 0;
});
//Create a BitArray from the bool array
BitArray boolBits = new BitArray(bools);
//Check if they contain correct values
bool isBitArrayCorrect = CompareBitArrays(controlGroup, bits); //FALSE
bool isBoolArrayCorrect = CompareBitArrays(controlGroup, boolBits); //TRUE
}
As I mentioned, I suspect the reason to be that 32 values in the BitArray share the same integral value of the array.
Is this logic correct?
For the sake of question, please assume no threads other than those shown in the code are accessing the collection.
Look into
BitArray.Setmethod code:As far as you accessing collection member by index, without enumerating it, the only thread-unsafe line of code I see there, is the last line
this._version++;.But it is there, so, you can consider this code as thread-unsafe.