/// <summary> /// Demonstrates the use of the APM with arbitrary delegates for performing /// a prime number calculation. The code performs a synchronous calculation first, /// and then interlaces two different calculation methods asynchronously and /// waits for them to complete. /// </summary> static void APMWithDelegates() { //Synchronous calculation: PrimeNumberCalculator calc = new PrimeNumberCalculator(5, 10000000); Measure.It(() => { Console.WriteLine("There are {0} primes using the sieve", calc.Calculate(PrimeNumberCalculation.Sieve)); }, "Synchronous calculation"); //Asynchronous calculation using delegates to perform BOTH calculations at the same time: Measure.It(delegate { PrimeNumberCalculator asyncSieve = new PrimeNumberCalculator(5, 10000000); Func<PrimeNumberCalculation, int> asyncSieveCalculate = asyncSieve.Calculate; IAsyncResult sieveAR = asyncSieveCalculate.BeginInvoke(PrimeNumberCalculation.Sieve, null, null); PrimeNumberCalculator asyncStandard = new PrimeNumberCalculator(5, 10000000); Func<PrimeNumberCalculation, int> asyncStandardCalculate = asyncStandard.Calculate; IAsyncResult standardAR = asyncStandardCalculate.BeginInvoke(PrimeNumberCalculation.Sieve, null, null); //Polling the IsCompleted property of both async results every 100ms: while (!(sieveAR.IsCompleted && standardAR.IsCompleted)) Thread.Sleep(100); Console.WriteLine("There are {0} primes using the sieve", asyncSieveCalculate.EndInvoke(sieveAR)); Console.WriteLine("There are {0} primes using the standard method", asyncStandardCalculate.EndInvoke(standardAR)); }, "Asynchronous calculation using both methods"); }
/// <summary> /// Demonstrates the various ways to poll for asynchronous work to complete: /// Using the IsCompleted property, waiting for the wait handle embedded in the /// IAsyncResult object, and using a callback that is invoked when the operation /// completes. Both an anonymous method and a regular method are used as callbacks. /// </summary> private static void APMVariousWaysToEnd() { PrimeNumberCalculator calc = new PrimeNumberCalculator(5, 100000); Func<PrimeNumberCalculation, int> invoker = calc.Calculate; //Poll for IsCompleted property: IAsyncResult ar = invoker.BeginInvoke(PrimeNumberCalculation.Sieve, null, null); while (!ar.IsCompleted) Thread.Sleep(100); int result = invoker.EndInvoke(ar); //Wait for the wait handle: ar = invoker.BeginInvoke(PrimeNumberCalculation.Sieve, null, null); ar.AsyncWaitHandle.WaitOne(); result = invoker.EndInvoke(ar); //Use callback ar = invoker.BeginInvoke(PrimeNumberCalculation.Sieve, delegate { //Note that because we're using a closure (anonymous method), //we have access to the enclosing scope, so we don't have to //think about how the invoker and ar variables end up inside the //callback method. result = invoker.EndInvoke(ar); }, null); //Use callback without closures: Printer printer = new Printer(); ar = invoker.BeginInvoke(PrimeNumberCalculation.Sieve, new AsyncCallback(CalculationEnded), printer); }