I am working through a Parallel Programming example on Race conditions
In the example they are demonstrating the isolation patter to deal with race conditions
Why is it in this example following that a race condition does not occur when creating the task and the stateObject is passed as part of the task creation
I understand that we use isolatedBalance to do the updateing …but at the point where we assign the isolatedbalance = (int)stateObject could not another tasks finished balance be there i.e not 0 but 100 ???
So if there where enough tasks and that the task scheduler started an early task and it finished at a point when a later task is being created and assinged the account.Balance value would be 100 etc for when 1 of the tasks had finshed for a taks that was starting
class BankAccount
{
public int Balance { get; set; }
}
class Program
{
static void Main(string[] args)
{
var account = new BankAccount();
var tasks = new Task<int>[1000];
for (int i = 0; i < 1000; i++)
{
tasks[i] = new Task<int>((stateObject)=>
{
int isobalance = (int) stateObject;
for (int j = 0; j < 1000; j++)
{
isobalance ++;
}
return isobalance;
}, account.Balance);
tasks[i].Start();
}
Task.WaitAll(tasks);
for (int i = 0; i < 1000; i++)
{
account.Balance += tasks[i].Result;
}
Console.WriteLine("Epectecd valeu {0}, Counter value {1}",1000000,account.Balance);
// wait for input before exiting
Console.WriteLine("Press enter to finish");
Console.ReadLine();
}
}
The method that you have passed to the
Taskconstructor does not updateaccount.Balanceit only uses the initial value ofaccount.Balance. It does not update it.intis pass by value. From MSDN:A value-type variable contains its data directly as opposed to a reference-type variable, which contains a reference to its data. Therefore, passing a value-type variable to a method means passing a copy of the variable to the method. Any changes to the parameter that take place inside the method have no affect on the original data stored in the variable. If you want the called method to change the value of the parameter, you have to pass it by reference, using the ref or out keyword. For simplicity, the following examples use ref.
Therefore
account.Balanceis not updated until afterTask.WaitAll(tasks);is called.Task.WaitAll()causes the code to stop there until all tasks have finished. Only after that, once all the results have been computed. willaccount.Balancebe updated with the values returned fromtasks[i].Result.