I started to learn Asynchronous programming in C# 5 and .Net 4.5 and there is something I don’t understand.
private static int count;
public static void Main()
{
LoopTest();
Console.ReadKey(false);
}
static async void LoopTest()
{
count = 0;
for (var index = 0; index < 10; ++index)
{
Console.WriteLine( "({0}) In Loop before await, Index {1}, Thread: {2}", count++, index, Thread.CurrentThread.ManagedThreadId);
await Task.Factory.StartNew(() => Thread.Sleep(10));
}
}
The result is:
(0) In Loop before await, Index 0, Thread: 9
(1) In Loop before await, Index 1, Thread: 10
(2) In Loop before await, Index 2, Thread: 11
(3) In Loop before await, Index 3, Thread: 10
(4) In Loop before await, Index 4, Thread: 11
(5) In Loop before await, Index 5, Thread: 10
(6) In Loop before await, Index 6, Thread: 12
(7) In Loop before await, Index 7, Thread: 11
(8) In Loop before await, Index 8, Thread: 10
(9) In Loop before await, Index 9, Thread: 12
So are there different Threads accessing the same loop? is there a Race-Condition on the index variable?
No, there is no race condition. You start a new task, that will run in the background, but your code will not continue until that task finishes, so you can be sure that your code will only be executed in one thread at any one time.
However, because this is a console application there is no current
SyncronizationContext. (As opposed to a winform, WPF, ASP, Silverlight, etc. application in which there will be.) This means that the continuations from anyawaitcall will run in the thread pool, not in the calling thread. So yes, you’re running in one of the thread pool threads in each iteration of the loop, and it could be a different one each time, but you can be sure that, excepting whatever you put inside the new task, you will “finish” running on any given thread before you start working on the next, which ensures that there is only ever one thread running code at any given time (which means no race conditions).