The problem is that your code is not thread-safe. For example, what can happen is this:
- function #2 gets the value of
counter
to use it inConsole.WriteLine()
- function #1 gets the value of
counter
, callsConsole.WriteLine()
, incrementscounter
- function #1 gets the value of
counter
, callsConsole.WriteLine()
, incrementscounter
- function #2 finally calls
Console.WriteLine()
with the old value
Also, ++
by itself is not thread-safe, so the final value may not be 15.
To fix both of these issues, you can use Interlocked.Increment()
:
for (int i = 0; i < 5; i++)
{
int incrementedCounter = Interlocked.Increment(ref counter);
Console.WriteLine("This is function #{0} loop. counter - {1}", num, incrementedCounter);
}
This way, you will get the number after increment, not before, as in your original code. Also, this code still won't print the numbers in the correct order, but you can be sure that each number will be printed exactly once.
If you do want to have the numbers in the correct order, you will need to use lock
:
private static readonly object lockObject = new object();
…
for (int i = 0; i < 5; i++)
{
lock (lockObject)
{
Console.WriteLine("This is function #{0} loop. counter - {1}", num, counter);
counter++;
}
}
Of course, if you do this, you won't actually get any parallelism, but I assume this is not your real code.