博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
异步编程设计模式Demo - PrimeNumberCalculator
阅读量:5086 次
发布时间:2019-06-13

本文共 12667 字,大约阅读时间需要 42 分钟。

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;            }        }    }}

  

转载于:https://www.cnblogs.com/chengshuiqiang/p/4479021.html

你可能感兴趣的文章
CPU,寄存器,一缓二缓.... RAM ROM 外部存储器等简介
查看>>
git .gitignore 文件不起作用
查看>>
Alan Turing的纪录片观后感
查看>>
c#自定义控件中的事件处理
查看>>
IOS--沙盒机制
查看>>
使用 JointCode.Shuttle 访问任意 AppDomain 的服务
查看>>
sqlite的坑
查看>>
digitalocean --- How To Install Apache Tomcat 8 on Ubuntu 16.04
查看>>
【题解】[P4178 Tree]
查看>>
Mongo自动备份
查看>>
cer证书签名验证
查看>>
synchronized
查看>>
【深度学习】caffe 中的一些参数介绍
查看>>
Python-Web框架的本质
查看>>
QML学习笔记之一
查看>>
Window 的引导过程
查看>>
App右上角数字
查看>>
从.NET中委托写法的演变谈开去(上):委托与匿名方法
查看>>
小算法
查看>>
201521123024 《java程序设计》 第12周学习总结
查看>>