Q:

Where is the race condition in this code snippet? (from C# 5.0 in a Nutshell)

This is from Joseph Albahari's excellent C# 5.0 in a Nutshell book
In one of his chapters, he mentions a race-condition in this code block ..my guess is it's meant to be pretty self-evident, as he didn't bother to specify where it was but running the code multiple times I was unable to produce the said-race condition
_button.Click += (sender, args) =>
{
   _button.IsEnabled = false;
   Task.Run (() => Go());
};

void Go()
{
    for (int i = 1; i < 5; i++)
    {
        int result = GetPrimesCount (i * 1000000, 1000000);
        Dispatcher.BeginInvoke (new Action (() =>
       _results.Text += result + " primes between " + (i*1000000) + " and " + 
                                   ((i+1)*1000000-1) + Environment.NewLine));
    }

    Dispatcher.BeginInvoke (new Action (() => _button.IsEnabled = true));
}

A:

I don't agree with @Serge's answer. You don't even need multiple threads to see the problem. Try to run your code in its original form and notice the output. For me it's the following and is sometimes random (I fixed the first value):
1000000 primes between 5000000 and 5999999
1000000 primes between 5000000 and 5999999
1000000 primes between 5000000 and 5999999
1000000 primes between 5000000 and 5999999

Notice the last 2 values. They're all the same, but they should depend on i. The problem is not that the operation is not atomic, because the GUI thread will execute the actions sequentially anyway.
The reason for this occurring is that the lambda function passed to BeginInvoke takes the value of i at the moment of execution, not at the moment of initialization, so they will all see the last value of i by the time they get executed. The solution is to explicitly pass i as a parameter to the lambda like so:
for (int i = 1; i < 5; i++)
{
    int result = 1000000;
    Dispatcher.BeginInvoke(new Action<int>(j =>
    results.Text += result + " primes between " + (j * 1000000) + " and " +
                              ((j + 1) * 1000000 - 1) + Environment.NewLine), i);
}

