zoukankan      html  css  js  c++  java
  • 异步编程设计模式Demo

    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Globalization;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace AsyncProgramDemo
    {
        public delegate void ProgressChangedEventHandler(ProgressChangedEventArgs e);
    
        public delegate void CalculatePrimeCompletedEventHandler(
            object sender,
            CalculatePrimeCompletedEventArgs e);
    
        public class PrimeNumberCalculator : Component
        {
            public event ProgressChangedEventHandler ProgressChanged;
            public event CalculatePrimeCompletedEventHandler CalculatePrimeCompleted;
    
            private SendOrPostCallback onProgressReportDelegate;
            private SendOrPostCallback onCompletedDelegate;
    
            protected virtual void InitializeDelegates()
            {
                onProgressReportDelegate =
                    new SendOrPostCallback(ReportProgress);
                onCompletedDelegate =
                    new SendOrPostCallback(CalculateCompleted);
            }
    
            private delegate void WorkerEventHandler(
                int numberToCheck,
                AsyncOperation asyncOp);
    
            private HybridDictionary userStateToLifetime =
                new HybridDictionary();
    
            public PrimeNumberCalculator()
            {
                //InitializeComponent();
    
                InitializeDelegates();
            }
    
            // 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(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.
            }
    
            // Utility method for determining if a 
            // task has been canceled.
            private bool TaskCanceled(object taskId)
            {
                return (userStateToLifetime[taskId] == null);
            }
    
            // This method performs the actual prime number computation.
            // It is executed on the worker thread.
            private void CalculateWorker(
                int numberToTest,
                AsyncOperation asyncOp)
            {
                bool isPrime = false;
                int firstDivisor = 1;
                Exception e = null;
    
                // Check that the task is still active.
                // The operation may have been canceled before
                // the thread was scheduled.
                if (!TaskCanceled(asyncOp.UserSuppliedState))
                {
                    try
                    {
                        // Find all the prime numbers up to 
                        // the square root of numberToTest.
                        ArrayList primes = BuildPrimeNumberList(
                            numberToTest,
                            asyncOp);
    
                        // Now we have a list of primes less than
                        // numberToTest.
                        isPrime = IsPrime(
                            primes,
                            numberToTest,
                            out firstDivisor);
                    }
                    catch (Exception ex)
                    {
                        e = ex;
                    }
                }
    
                //CalculatePrimeState calcState = new CalculatePrimeState(
                //        numberToTest,
                //        firstDivisor,
                //        isPrime,
                //        e,
                //        TaskCanceled(asyncOp.UserSuppliedState),
                //        asyncOp);
    
                //this.CompletionMethod(calcState);
    
                this.CompletionMethod(
                    numberToTest,
                    firstDivisor,
                    isPrime,
                    e,
                    TaskCanceled(asyncOp.UserSuppliedState),
                    asyncOp);
    
                //completionMethodDelegate(calcState);
            }
    
            // This method computes the list of prime numbers used by the
            // IsPrime method.
            private ArrayList BuildPrimeNumberList(
                int numberToTest,
                AsyncOperation asyncOp)
            {
                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))
                {
                    if (IsPrime(primes, n, out firstDivisor))
                    {
                        // Report to the client that a prime was found.
                        e = new CalculatePrimeProgressChangedEventArgs(
                            n,
                            (int)((float)n / (float)numberToTest * 100),
                            asyncOp.UserSuppliedState);
    
                        asyncOp.Post(this.onProgressReportDelegate, e);
                        Thread.Sleep(1);
                        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;
            }
    
            // 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)
            {
                // 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);
            }
    
            // This method cancels a pending asynchronous operation.
            public void CancelAsync(object taskId)
            {
                AsyncOperation asyncOp = userStateToLifetime[taskId] as AsyncOperation;
                if (asyncOp != null)
                {
                    lock (userStateToLifetime.SyncRoot)
                    {
                        userStateToLifetime.Remove(taskId);
                    }
                }
            }
    
        }
    
        public class CalculatePrimeCompletedEventArgs :
            AsyncCompletedEventArgs
        {
            private int numberToTestValue = 0;
            private int firstDivisorValue = 1;
            private bool isPrimeValue;
    
            public CalculatePrimeCompletedEventArgs(
                int numberToTest,
                int firstDivisor,
                bool isPrime,
                Exception e,
                bool canceled,
                object state)
                : base(e, canceled, state)
            {
                this.numberToTestValue = numberToTest;
                this.firstDivisorValue = firstDivisor;
                this.isPrimeValue = isPrime;
            }
    
            public int NumberToTest
            {
                get
                {
                    // Raise an exception if the operation failed or 
                    // was canceled.
                    RaiseExceptionIfNecessary();
    
                    // If the operation was successful, return the 
                    // property value.
                    return numberToTestValue;
                }
            }
    
            public int FirstDivisor
            {
                get
                {
                    // Raise an exception if the operation failed or 
                    // was canceled.
                    RaiseExceptionIfNecessary();
    
                    // If the operation was successful, return the 
                    // property value.
                    return firstDivisorValue;
                }
            }
    
            public bool IsPrime
            {
                get
                {
                    // Raise an exception if the operation failed or 
                    // was canceled.
                    RaiseExceptionIfNecessary();
    
                    // If the operation was successful, return the 
                    // property value.
                    return isPrimeValue;
                }
            }
        }
    
        public class CalculatePrimeProgressChangedEventArgs :
            ProgressChangedEventArgs
        {
            private int latestPrimeNumberValue = 1;
    
            public CalculatePrimeProgressChangedEventArgs(
                int latestPrime,
                int progressPercentage,
                object userToken)
                : base(progressPercentage, userToken)
            {
                this.latestPrimeNumberValue = latestPrime;
            }
    
            public int LatestPrimeNumber
            {
                get
                {
                    return latestPrimeNumberValue;
                }
            }
        }
    
    }
    

      

  • 相关阅读:
    关于div 浮动在select,或table控件之上
    页面table的每行都有一个<input type='button' />,如何实现点击按钮在按钮下方弹出一个div,点击空白消失
    BAT 遍历文件夹和子文件夹下所有文件
    在windows上一键编译各种版本的protobuf(2017-12-05修改)
    安装CentOS Core之后布置环境脚本
    优先级队列
    Ubuntu 设置Vim tab为四个空格
    Mysql 只导出数据,不包含表结构
    Kib Kb KB KIB 区别
    护眼色
  • 原文地址:https://www.cnblogs.com/chengshuiqiang/p/4479021.html
Copyright © 2011-2022 走看看