Yes, I know that the next question can be answered using "Use the lock keyword" or something similar. But since it’s just “fun,” I don’t care.
I made a simple lock using atomic operations:
public class LowLock
{
volatile int locked = 0;
public void Enter(Action action)
{
var s = new SpinWait();
while (true)
{
var inLock = locked;
if (Interlocked.CompareExchange(ref locked, 1, inLock) == 1)
{
action();
locked = 0;
break;
}
else s.SpinOnce();
}
}
}
I use the lock above in a simple for loop that adds a line to the normal List<string>one to make the method addthread safe when it is wrapped inside a method Enterfrom a LowLock.
The code looks like this:
static void Main(string[] args)
{
var numbers = new List<int>();
var sw = Stopwatch.StartNew();
var cd = new CountdownEvent(10000);
for (int i = 0; i < 10000; i++)
{
ThreadPool.QueueUserWorkItem(o =>
{
low.Enter(() => numbers.Add(i));
cd.Signal();
});
}
cd.Wait();
sw.Stop();
Console.WriteLine("Time = {0} | results = {1}", sw.ElapsedMilliseconds, numbers.Count);
Console.ReadKey();
}
, , Console.WriteLine, , , CountdownEvent (10000) - It , 9983 , - 9993. ?