static void Main(string[] args) { // Get the currently-running thread object. Thread primaryThreadObject = Thread.CurrentThread; // Set the name of the thread. This will help with debugging // when looking at the Threads window. primaryThreadObject.Name = "The Main Thread"; // Get the thread ID so that we can use it in output statements. int threadId = primaryThreadObject.ManagedThreadId; try { // Display a message to show we're in Main(). Console.WriteLine("{0}: Starting the program.", threadId); // Get the number of milliseconds from the arguments // passed in from the command line. int milliseconds = GetMilliseconds(args[0]); // Create the ComplicatedCalculator objects. ComplicatedCalculator cc1 = new ComplicatedCalculator(milliseconds); ComplicatedCalculator cc2 = new ComplicatedCalculator(milliseconds); ComplicatedCalculator cc3 = new ComplicatedCalculator(milliseconds); ComplicatedCalculator cc4 = new ComplicatedCalculator(milliseconds); // Create the ParameterizedThreadStart delegate. This // delegate will be used to pass an array of doubles // to the method on the secondary thread. // First run using the set of arguments below. double[] numbers1 = { 10.4, 7.451 }; double[] numbers2 = { 18.7, 3.6 }; double[] numbers3 = { 12.7, 8.6 }; double[] numbers4 = { 15.2, 5.3 }; // Second run with set of arguments below showing that the // results are no different whether or not lambda // expressions are used. //double[] numbers1 = { 10.4, 7.451 }; //double[] numbers2 = { 10.4, 7.451 }; //double[] numbers3 = { 10.4, 7.451 }; //double[] numbers4 = { 10.4, 7.451 }; ParameterizedThreadStart threadedMethod1 = new ParameterizedThreadStart(cc1.CalculateValue); // Create the thread objects and start the threads. In this // case, when we call Start(), we pass in the double array // as an argument. // All 4 ways of creating a thread instance below, causes the // ParameterizedThreadStart delegate to be generated by the compiler. // Creates an instance of a thread that is assigned a // ParameterizedThreadStart delegate. Thread secondaryThread1 = new Thread(threadedMethod1); // Creates a new thread that is implicitly assigned a ParameterizedThreadStart // delegate for the new thread. Thread secondaryThread2 = new Thread(cc2.CalculateValue); // Use a lambda expression to create a new thread that is implicitly assigned a // ParameterizedThreadStart delegate. Thread secondaryThread3 = new Thread((Object obj) => cc3.CalculateValue(obj)); // Use a lambda expression to create a new thread that is implicitly assigned a // ParameterizedThreadStart delegate. Thread secondaryThread4 = new Thread((obj) => { cc4.CalculateValue(obj); }); // Set the name of the secondary threads. secondaryThread1.Name = "Calculation Thread #1"; secondaryThread2.Name = "Calculation Thread #2"; secondaryThread3.Name = "Calculation Thread #3"; secondaryThread4.Name = "Calculation Thread #4"; // Start the threads. secondaryThread1.Start(numbers1); secondaryThread2.Start(numbers2); secondaryThread3.Start(numbers3); secondaryThread4.Start(numbers4); // Display some messages to show that Main() is still // responsive while the calculation is going on. Console.WriteLine ("\n{0}: Now I'm going to go do something else.", threadId); System.Threading.Thread.Sleep(1500); Console.WriteLine("\n{0}: Like talk about the weather.", threadId); System.Threading.Thread.Sleep(1500); Console.WriteLine("\n{0}: Or the latest news.", threadId); System.Threading.Thread.Sleep(1500); Console.WriteLine("\n{0}: You know, my foot hurts.", threadId); System.Threading.Thread.Sleep(1500); Console.WriteLine("\n{0}: I love hotdogs!", threadId); System.Threading.Thread.Sleep(1500); Console.WriteLine ("\n{0}: How much is a shake at Burgermaster?", threadId); System.Threading.Thread.Sleep(1500); Console.WriteLine("\n{0}: Ok, now I'm getting hungry!", threadId); System.Threading.Thread.Sleep(1500); // Join one of the secondary threads. JoinThread(threadId, secondaryThread1); // Join the other secondary thread. JoinThread(threadId, secondaryThread2); // Join the other secondary thread. JoinThread(threadId, secondaryThread3); // Join the other secondary thread. JoinThread(threadId, secondaryThread4); Console.WriteLine("\n{0}: The result from {1} is: {2}", threadId, secondaryThread1.ManagedThreadId, cc1.Results); Console.WriteLine("\n{0}: The result from {1} is: {2}", threadId, secondaryThread2.ManagedThreadId, cc2.Results); Console.WriteLine("\n{0}: The result from {1} is: {2}", threadId, secondaryThread3.ManagedThreadId, cc3.Results); Console.WriteLine("\n{0}: The result from {1} is: {2}", threadId, secondaryThread4.ManagedThreadId, cc4.Results); } catch (Exception e) { Console.WriteLine("\n{0}: EXCEPTION: {1}.", threadId, e.Message); } // Pause so we can look at the console window. Console.Write("\n\n{0}: Press <ENTER> to end: ", threadId); Console.ReadLine(); }