I just wonder whether a race condition occurs in the code below:
int readingFiles;
async Task ReadFile (string file)
{
++readingFiles;
There is no race condition here. The .NET runtime will insert the appropriate memory barriers.
Also see the comments on: http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx
Yes, TPL includes the appropriate barriers when tasks are queued and at the beginning/end of task execution so that values are appropriately made visible.
There are a number of things that could be going on here.
For one, what sort of executable are you running? When Await fires, it uses the current synchronization context, so your awaited code could be getting serialized to 1 a UI thread.
Also, since there is no memory barrier/volatility protection around the variable, your threads might be reading indiviually cached values (as mentioned by @Spo1ler in his post)
Also, the thread pool might be choosing to run both your requests on the same thread (it's within its rights to do so -- you're letting .net/windows decide when and how to allocate threads)
Bottom line though, you really should be protecting the access to the variable with synchronization or interlocked operations.