Recently I\'ve seen some C# projects that use a double-checked-lock pattern on a Dictionary. Something like this:
private static readonly object
Including the code in the question, you can test it with the following code.
//using System.Collections.Generic;
//using System.Threading;
private static volatile int numRunning = 2;
private static volatile int spinLock = 0;
static void Main(string[] args)
{
new Thread(TryWrite).Start();
new Thread(TryWrite).Start();
}
static void TryWrite()
{
while(true)
{
for (int i = 0; i < 1000000; i++ )
{
Create(i.ToString());
}
Interlocked.Decrement(ref numRunning);
while (numRunning > 0) { } // make sure every thread has passed the previous line before proceeding (call this barrier 1)
while (Interlocked.CompareExchange(ref spinLock, 1, 0) != 0){Thread.Sleep(0);} // Aquire lock (spin lock)
// only one thread can be here at a time...
if (numRunning == 0) // only the first thread to get here executes this...
{
numRunning = 2; // resets barrier 1
// since the other thread is beyond the barrier, but is waiting on the spin lock,
// nobody is accessing the cache, so we can clear it...
_cache = new Dictionary(); // clear the cache...
}
spinLock = 0; // release lock...
}
}
This program just tries to get Create to traverse the collection as it is being "grown". It should be run on a machine with at least two cores (or two processors), and will most likely fail after a while with this exception.
System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
Adding this test is difficult since it is a probabilistic test, and you don't know how long it will take to fail (if ever). I guess you could pick a value like 10 seconds and let it run for that long. If it doesn't fail in that amount of time, then the test passes. Not the best, but something. You should also verify that Environment.ProcessorCount > 1 before running the test, otherwise the likelihood of it failing is minuscule.