static void Ex15() { //this Bank has an Event it's waiting for //in order to proceed with the Transfer. ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount() { Id = 1 }; ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount() { Id = 2 }; ba1.Deposit(100); ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank(); for (int i = 0; i < 100; i++) //200 concurrent Threads running transfer { new Thread(() => { bank.Transfer(ba1, ba2, 50); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); }).Start(); new Thread(() => { bank.Transfer(ba2, ba1, 50); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); }).Start(); } }
static void Ex03() { //This example is equivalent to Ex15 of the Thread examples, //but it's faster because it does not spawn 200 new Threads //and it uses the ThreadPool instead. ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount() { Id = 1 }; ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount() { Id = 2 }; ba1.Deposit(100); ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank(); for (int i = 0; i < 100; i++) //200 concurrent Threads running transfer { ThreadPool.QueueUserWorkItem(_ => { bank.Transfer(ba1, ba2, 50); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); }); ThreadPool.QueueUserWorkItem(_ => { bank.Transfer(ba2, ba1, 50); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); }); } }
static void Ex17() { //In this scenario we want to wait for all Thread to finish //before we continue. //Another thing we could do is to create just one event //and set it when a counter reaches 200. //BUT we have to increase the same counter on 200 different threads, //meaning that we have to do it in a thread safe manner. AutoResetEvent doneEvent = new AutoResetEvent(false); ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount() { Id = 1 }; ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount() { Id = 2 }; ba1.Deposit(100); ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank(); int counter = 0; for (int i = 0; i < 100; i++) //200 concurrent Threads running transfer { new Thread(() => { bank.Transfer(ba1, ba2, 50); Interlocked.Increment(ref counter); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); if (counter == 200) { doneEvent.Set(); } }).Start(); new Thread(() => { bank.Transfer(ba2, ba1, 50); Interlocked.Increment(ref counter); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); if (counter == 200) { doneEvent.Set(); } }).Start(); } doneEvent.WaitOne(); Console.WriteLine("DONE!!"); }
static void Ex16() { //In this scenario we want to wait for all Thread to finish //before we continue. //We could create 200 AutoResetEvents, put them in an Array, //signal each one of them from a Thread //and use EventWaitHandle.WaitAll, //but they would be too many. AutoResetEvent[] events = Enumerable.Repeat(new AutoResetEvent(false), 200).ToArray(); ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount() { Id = 1 }; ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount() { Id = 2 }; ba1.Deposit(100); ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank(); for (int i = 0; i < 100; i++) //200 concurrent Threads running transfer { new Thread(() => { bank.Transfer(ba1, ba2, 50); events[i].Set(); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); }).Start(); new Thread(() => { bank.Transfer(ba2, ba1, 50); events[i + 100].Set(); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); }).Start(); } //boom! WaitHandle.WaitAll(events); Console.WriteLine("DONE!!"); }
static void Ex18() { //In this scenario we want to wait for all Thread to finish //before we continue. //Another thing we could do is to use a CountdownEvent. CountdownEvent doneEvent = new CountdownEvent(200); ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount() { Id = 1 }; ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount() { Id = 2 }; ba1.Deposit(100); ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank(); for (int i = 0; i < 100; i++) //200 concurrent Threads running transfer { new Thread(() => { bank.Transfer(ba1, ba2, 50); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); doneEvent.Signal(); }).Start(); new Thread(() => { bank.Transfer(ba2, ba1, 50); Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); doneEvent.Signal(); }).Start(); } doneEvent.Wait(); //waiting for it to reach 0 Console.WriteLine("DONE!!"); }