static void Main(string[] args) { // create the array of bank accounts BankAccount[] accounts = new BankAccount[5]; for (int i = 0; i < accounts.Length; i++) { accounts[i] = new BankAccount(); } // create the total balance counter int totalBalance = 0; // create the barrier Barrier barrier = new Barrier(5, (myBarrier) => { // zero the balance totalBalance = 0; // sum the account totals foreach (BankAccount account in accounts) { totalBalance += account.Balance; } // write out the balance Console.WriteLine("Total balance: {0}", totalBalance); }); // define the tasks array Task[] tasks = new Task[5]; // loop to create the tasks for (int i = 0; i < tasks.Length; i++) { tasks[i] = new Task((stateObj) => { // create a typed reference to the account BankAccount account = (BankAccount)stateObj; // start of phase Random rnd = new Random(); for (int j = 0; j < 1000; j++) { account.Balance += rnd.Next(1, 100); } // end of phase // tell the user that this task has has completed the phase Console.WriteLine("Task {0}, phase {1} ended", Task.CurrentId, barrier.CurrentPhaseNumber); // signal the barrier barrier.SignalAndWait(); // start of phase // alter the balance of this Task's account using the total balance // deduct 10% of the difference from the total balance account.Balance -= (totalBalance - account.Balance) / 10; // end of phase // tell the user that this task has has completed the phase Console.WriteLine("Task {0}, phase {1} ended", Task.CurrentId, barrier.CurrentPhaseNumber); // signal the barrier barrier.SignalAndWait(); }, accounts[i]); } // start the task foreach (Task t in tasks) { t.Start(); } // wait for all of the tasks to complete Task.WaitAll(tasks); // wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine(); }
static void Main(string[] args) { // create the bank account instances BankAccount account1 = new BankAccount(); BankAccount account2 = new BankAccount(); // create the mutexes Mutex mutex1 = new Mutex(); Mutex mutex2 = new Mutex(); // create a new task to update the first account Task task1 = new Task(() => { // enter a loop for 1000 balance updates for (int j = 0; j < 1000; j++) { // acquire the lock for the account bool lockAcquired = mutex1.WaitOne(); try { // update the balance account1.Balance++; } finally { if (lockAcquired) mutex1.ReleaseMutex(); } } }); // create a new task to update the first account Task task2 = new Task(() => { // enter a loop for 1000 balance updates for (int j = 0; j < 1000; j++) { // acquire the lock for the account bool lockAcquired = mutex2.WaitOne(); ; try { // update the balance account2.Balance += 2; } finally { if (lockAcquired) mutex2.ReleaseMutex(); } } }); // create a new task to update the first account Task task3 = new Task(() => { // enter a loop for 1000 balance updates for (int j = 0; j < 1000; j++) { // acquire the locks for both accounts bool lockAcquired = Mutex.WaitAll(new WaitHandle[] { mutex1, mutex2 }); try { // simulate a transfer between accounts account1.Balance++; account2.Balance--; } finally { if (lockAcquired) { mutex1.ReleaseMutex(); mutex2.ReleaseMutex(); } } } }); // start the tasks task1.Start(); task2.Start(); task3.Start(); // wait for the tasks to complete Task.WaitAll(task1, task2, task3); // write out the counter value Console.WriteLine("Account1 balance {0}, Account2 balance: {1}", account1.Balance, account2.Balance); // wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine(); }