MSDN version AsyncFunc version Description
using System;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
 
using System.Collections.Specialized;   You don't need to reference rarely used namespaces!
 
namespace MsdnExample
{
    #region PrimeNumberCalculator Implementation
 
 
namespace MsdnExample
{
    #region PrimeNumberCalculator Implementation
 
 
   public delegate void CalculatePrimeCompletedEventHandler(
        object sender,
        CalculatePrimeCompletedEventArgs e);
  You don't need to declare additional event handlers!
 
    // This class implements the Event-based Asynchronous Pattern.
    // It asynchronously computes whether a number is prime or
    // composite (not prime).
    public class OriginalPrimeNumberCalculator
    {
    // This class implements the Event-based Asynchronous Pattern.
    // It asynchronously computes whether a number is prime or
    // composite (not prime).
    public class OriginalPrimeNumberCalculator
    {
          private AsyncFuncMultipleInvocation<int, CalculatePrimeResult> _func; One instance of AsyncFunc is all you need!
        private delegate void WorkerEventHandler(
            int numberToCheck,
            AsyncOperation asyncOp);
  You don't need to declare new delegates!
     
        private SendOrPostCallback onProgressReportDelegate;
        private SendOrPostCallback onCompletedDelegate;
  You dont need to know how to execute callback on different thread!
     
        private HybridDictionary userStateToLifetime =
            new HybridDictionary();
  You don't need to manage collection of background tasks!
 
        /////////////////////////////////////////////////////////////
        #region Public events
 
        public event ProgressChangedEventHandler ProgressChanged;
 
        /////////////////////////////////////////////////////////////
        #region Public events
 
        public event ProgressChangedEventHandler ProgressChanged;
 
          {
            add { _func.ProgressChanged += value; }
            remove { _func.ProgressChanged -= value; }
        }
You can pretend that your class implements Event-based Asynchronous Pattern by delegating calls to AsyncFunc instance!
        public event CalculatePrimeCompletedEventHandler CalculatePrimeCompleted;         public event AsyncFuncCompletedEventHandler<CalculatePrimeResult> CalculatePrimeCompleted  
          {
            add { _func.Completed += value; }
            remove { _func.Completed -= value; }
        }
You can pretend that your class implements Event-based Asynchronous Pattern by delegating calls to AsyncFunc instance!
 
        #endregion
 
        /////////////////////////////////////////////////////////////
        #region Construction and destruction
 
        public OriginalPrimeNumberCalculator()
        {
 
        #endregion
 
        /////////////////////////////////////////////////////////////
        #region Construction and destruction
 
        public OriginalPrimeNumberCalculator()
        {
 
            InitializeDelegates();             _func = new AsyncFuncMultipleInvocation<int, CalculatePrimeResult>(CalculateWorker);  
        }
 
        }
 
 
        protected virtual void InitializeDelegates()
        {
            onProgressReportDelegate =
                new SendOrPostCallback(ReportProgress);
            onCompletedDelegate =
                new SendOrPostCallback(CalculateCompleted);
        }
  You don't need to do complicated initialization!
 
        #endregion // Construction and destruction
 
        /////////////////////////////////////////////////////////////
        ///
        #region Implementation
 
        // This method starts an asynchronous calculation.
        // First, it checks the supplied task ID for uniqueness.
        // If taskId is unique, it creates a new WorkerEventHandler
        // and calls its BeginInvoke method to start the calculation.
        public virtual void CalculatePrimeAsync(
            int numberToTest,
            object taskId)
        {
 
        #endregion // Construction and destruction
 
        /////////////////////////////////////////////////////////////
        ///
        #region Implementation
 
        // This method starts an asynchronous calculation.
        // First, it checks the supplied task ID for uniqueness.
        // If taskId is unique, it creates a new WorkerEventHandler
        // and calls its BeginInvoke method to start the calculation.
        public virtual void CalculatePrimeAsync(
            int numberToTest,
            object taskId)
        {
              _func.InvokeAsync(numberToTest, taskId) If you want to invoke function asynchronously, just do it!
            // Create an AsyncOperation for taskId.
            AsyncOperation asyncOp =
                AsyncOperationManager.CreateOperation(taskId);
 
            // Multiple threads will access the task dictionary,
            // so it must be locked to serialize access.
            lock (userStateToLifetime.SyncRoot)
            {
                if (userStateToLifetime.Contains(taskId))
                {
                    throw new ArgumentException(
                        "Task ID parameter must be unique",
                        "taskId");
                }
 
                userStateToLifetime[taskId] = asyncOp;
            }
 
            // Start the asynchronous operation.
            WorkerEventHandler workerDelegate = new WorkerEventHandler(
                CalculateWorker);
            workerDelegate.BeginInvoke(
                numberToTest,
                asyncOp,
                null,
                null);
                taskId);
  You don't need to know what AsyncOperationManager is and how to use it!
You don't need to care about synchronization issues!
You don't need to know how to invoke delegate asynchronously!
        }
 
        // This method cancels a pending asynchronous operation.
        public void CancelAsync(object taskId)
        {
        }
 
        // This method cancels a pending asynchronous operation.
        public void CancelAsync(object taskId)
        {
              _func.Cancel(taskId); If you want to cancel asynchronous function, just do it!
            AsyncOperation asyncOp = userStateToLifetime[taskId] as AsyncOperation;
            if (asyncOp != null)
            {
                lock (userStateToLifetime.SyncRoot)
                {
                    userStateToLifetime.Remove(taskId);
                }
            }
  You don't need to care about synchronization issues!
        }
 
        // This method performs the actual prime number computation.
        // It is executed on the worker thread.
        }
 
        // This method performs the actual prime number computation.
        // It is executed on the worker thread.
 
        private void CalculateWorker(         private CalculatePrimeResult CalculateWorker( You can explicityly return result from your worker method!
            int numberToTest,             int numberToTest,  
            AsyncOperation asyncOp)    
              Func<bool> cancelled,
            Action<int> reportProgress)
 
        {
            bool isPrime = false;
            int firstDivisor = 1;
        {
            bool isPrime = false;
            int firstDivisor = 1;
 
            Exception e = null;   You don't need to create extra variables to store exceptions!
 
            // Check that the task is still active.
            // The operation may have been canceled before
            // the thread was scheduled.
 
            // Check that the task is still active.
            // The operation may have been canceled before
            // the thread was scheduled.
 
            if (!TaskCanceled(asyncOp.UserSuppliedState))             if (!cancelled()) If you want to check if the operation was cancelled, just do it!
            {             {  
                try
                {
  You don't need handle exceptions in the background thread!
                    // Find all the prime numbers up to
                    // the square root of numberToTest.
                    ArrayList primes = BuildPrimeNumberList(
                        numberToTest,
                    // Find all the prime numbers up to
                    // the square root of numberToTest.
                    ArrayList primes = BuildPrimeNumberList(
                        numberToTest,
 
                        asyncOp);    
                      cancelled,
                    reportProgress);
 
 
                    // Now we have a list of primes less than
                    // numberToTest.
                    isPrime = IsPrime(
                        primes,
                        numberToTest,
                        out firstDivisor);
 
                    // Now we have a list of primes less than
                    // numberToTest.
                    isPrime = IsPrime(
                        primes,
                        numberToTest,
                        out firstDivisor);
 
                }
                catch (Exception ex)
                {
                    e = ex;                 }
  You don't need handle exceptions in the background thread!
            }
 
            }
 
 
              return new CalculatePrimeResult(
                numberToTest,
                firstDivisor,
                isPrime);
When you finish just return the result!
            this.CompletionMethod(
                numberToTest,
                firstDivisor,
                isPrime,
                e,
                TaskCanceled(asyncOp.UserSuppliedState),
                asyncOp);
 
  You don't need do extra work to raise completion event!
        }
 
        // This method computes the list of prime numbers used by the
        // IsPrime method.
        private ArrayList BuildPrimeNumberList(
            int numberToTest,
        }
 
        // This method computes the list of prime numbers used by the
        // IsPrime method.
        private ArrayList BuildPrimeNumberList(
            int numberToTest,
 
            AsyncOperation asyncOp)    
              Func<bool> cancelled,
            Action<int> reportProgress)
 
        {
            ProgressChangedEventArgs e = null;
            ArrayList primes = new ArrayList();
            int firstDivisor;
            int n = 5;
 
            // Add the first prime numbers.
            primes.Add(2);
            primes.Add(3);
 
            // Do the work.
            while (n < numberToTest &&
        {
            ProgressChangedEventArgs e = null;
            ArrayList primes = new ArrayList();
            int firstDivisor;
            int n = 5;
 
            // Add the first prime numbers.
            primes.Add(2);
            primes.Add(3);
 
            // Do the work.
            while (n < numberToTest &&
 
                   !TaskCanceled(asyncOp.UserSuppliedState))                    !cancelled()) If you want to check if the operation was cancelled, just do it!
            {
                if (IsPrime(primes, n, out firstDivisor))
                {
                    // Report to the client that a prime was found.
            {
                if (IsPrime(primes, n, out firstDivisor))
                {
                    // Report to the client that a prime was found.
                reportProgress(
                  (int)((float)n / (float)numberToTest * 100));
If you want to report progress, just do it!
                    e = new ProgressChangedEventArgs(
                        (int)((float)n / (float)numberToTest * 100),
                        asyncOp.UserSuppliedState);
                       
 
                    asyncOp.Post(this.onProgressReportDelegate, e);
 
  If don't need to create any temporary variabled when you want to report progress!
                    primes.Add(n);
 
                    // Yield the rest of this time slice.
                    Thread.Sleep(0);
                }
 
                // Skip even numbers.
                n += 2;
            }
 
            return primes;
        }
 
        // This method tests n for primality against the list of
        // prime numbers contained in the primes parameter.
        private bool IsPrime(
            ArrayList primes,
            int n,
            out int firstDivisor)
        {
            bool foundDivisor = false;
            bool exceedsSquareRoot = false;
 
            int i = 0;
            int divisor = 0;
            firstDivisor = 1;
 
            // Stop the search if:
            // there are no more primes in the list,
            // there is a divisor of n in the list, or
            // there is a prime that is larger than
            // the square root of n.
            while (
                (i < primes.Count) &&
                !foundDivisor &&
                !exceedsSquareRoot)
            {
                // The divisor variable will be the smallest
                // prime number not yet tried.
                divisor = (int)primes[i++];
 
                // Determine whether the divisor is greater
                // than the square root of n.
                if (divisor * divisor > n)
                {
                    exceedsSquareRoot = true;
                }
                // Determine whether the divisor is a factor of n.
                else if (n % divisor == 0)
                {
                    firstDivisor = divisor;
                    foundDivisor = true;
                }
            }
 
            return !foundDivisor;
        }
 
                    primes.Add(n);
 
                    // Yield the rest of this time slice.
                    Thread.Sleep(0);
                }
 
                // Skip even numbers.
                n += 2;
            }
 
            return primes;
        }
 
        // This method tests n for primality against the list of
        // prime numbers contained in the primes parameter.
        private bool IsPrime(
            ArrayList primes,
            int n,
            out int firstDivisor)
        {
            bool foundDivisor = false;
            bool exceedsSquareRoot = false;
 
            int i = 0;
            int divisor = 0;
            firstDivisor = 1;
 
            // Stop the search if:
            // there are no more primes in the list,
            // there is a divisor of n in the list, or
            // there is a prime that is larger than
            // the square root of n.
            while (
                (i < primes.Count) &&
                !foundDivisor &&
                !exceedsSquareRoot)
            {
                // The divisor variable will be the smallest
                // prime number not yet tried.
                divisor = (int)primes[i++];
 
                // Determine whether the divisor is greater
                // than the square root of n.
                if (divisor * divisor > n)
                {
                    exceedsSquareRoot = true;
                }
                // Determine whether the divisor is a factor of n.
                else if (n % divisor == 0)
                {
                    firstDivisor = divisor;
                    foundDivisor = true;
                }
            }
 
            return !foundDivisor;
        }
 
Your processing logic stays the same!
        // Utility method for determining if a
        // task has been canceled.
        private bool TaskCanceled(object taskId)
        {
            return (userStateToLifetime[taskId] == null);
        }
 
        // This method is invoked via the AsyncOperation object,
        // so it is guaranteed to be executed on the correct thread.
        private void CalculateCompleted(object operationState)
        {
            CalculatePrimeCompletedEventArgs e =
                operationState as CalculatePrimeCompletedEventArgs;
 
            OnCalculatePrimeCompleted(e);
        }
 
        // This method is invoked via the AsyncOperation object,
        // so it is guaranteed to be executed on the correct thread.
        private void ReportProgress(object state)
        {
            ProgressChangedEventArgs e =
                state as ProgressChangedEventArgs;
 
            OnProgressChanged(e);
        }
 
        protected void OnCalculatePrimeCompleted(
            CalculatePrimeCompletedEventArgs e)
        {
            if (CalculatePrimeCompleted != null)
            {
                CalculatePrimeCompleted(this, e);
            }
        }
 
        protected void OnProgressChanged(ProgressChangedEventArgs e)
        {
            if (ProgressChanged != null)
            {
                ProgressChanged(this, e);
            }
        }
 
        // This is the method that the underlying, free-threaded
        // asynchronous behavior will invoke.  This will happen on
        // an arbitrary thread.
        private void CompletionMethod(
            int numberToTest,
            int firstDivisor,
            bool isPrime,
            Exception exception,
            bool canceled,
            AsyncOperation asyncOp)
        {
            // If the task was not previously canceled,
            // remove the task from the lifetime collection.
            if (!canceled)
            {
                lock (userStateToLifetime.SyncRoot)
                {
                    userStateToLifetime.Remove(asyncOp.UserSuppliedState);
                }
            }
 
            // Package the results of the operation in a
            // CalculatePrimeCompletedEventArgs.
            CalculatePrimeCompletedEventArgs e =
                new CalculatePrimeCompletedEventArgs(
                numberToTest,
                firstDivisor,
                isPrime,
                exception,
                canceled,
                asyncOp.UserSuppliedState);
 
            // End the task. The asyncOp object is responsible
            // for marshaling the call.
            asyncOp.PostOperationCompleted(onCompletedDelegate, e);
 
            // Note that after the call to OperationCompleted,
            // asyncOp is no longer usable, and any attempt to use it
            // will cause an exception to be thrown.
        }
 
 
  You don't need to create any helper methods!
        #endregion
 
    }
 
        #endregion
 
    }
 
 
    public class CalculatePrimeCompletedEventArgs :     public class CalculatePrimeResult  
        AsyncCompletedEventArgs   Your result class doesn't have to inherit from AsyncCompletedEventArgs!
    {     {  
        private int numberToTestValue = 0;
        private int firstDivisorValue = 1;
        private bool isPrimeValue;
   
     
        public CalculatePrimeCompletedEventArgs(         public CalculatePrimeResult(  
            int numberToTest,
            int firstDivisor,
            bool isPrime,
            int numberToTest,
            int firstDivisor,
            bool isPrime,
 
            Exception e,
            bool canceled,
            object state)
            : base(e, canceled, state)
  Your result class can store just the result without the need of storing anything specyfic to Event-based Asynchronous Pattern!
        {         {  
            this.numberToTestValue = numberToTest;
            this.firstDivisorValue = firstDivisor;
            this.isPrimeValue = isPrime;
            NumberToTest = numberToTestValue;
            FirstDivisor = firstDivisorValue;
            IsPrime = IsPrime;
 
        }
 
        }
 
 
        public int NumberToTest         public int NumberToTest { get; private set; }  
        {
            get
            {
                // Raise an exception if the operation failed or
                // was canceled.
                RaiseExceptionIfNecessary();
 
                // If the operation was successful, return the
                // property value.
                return numberToTestValue;
            }
        }
 
  You don't need raise any exceptions from accessors in your result class!
        public int FirstDivisor         public int FirstDivisor { get; private set; }  
        {
            get
            {
                // Raise an exception if the operation failed or
                // was canceled.
                RaiseExceptionIfNecessary();
 
                // If the operation was successful, return the
                // property value.
                return firstDivisorValue;
            }
        }
 
  You don't need raise any exceptions from accessors in your result class!
        public bool IsPrime         public bool IsPrime { get; private set; }  
        {
            get
            {
                // Raise an exception if the operation failed or
                // was canceled.
                RaiseExceptionIfNecessary();
 
                // If the operation was successful, return the
                // property value.
                return isPrimeValue;
            }
        }
  You don't need raise any exceptions from accessors in your result class!
    }
 
 
    #endregion
}
    }
 
 
    #endregion
}
 

Last edited Dec 18, 2010 at 3:25 PM by StanislawSwierc, version 6

Comments

No comments yet.