异步编程设计模式Demo - PrimeNumberCalculator
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;
}
}
} }
异步编程设计模式Demo - PrimeNumberCalculator的更多相关文章
- 异步编程设计模式Demo - AsyncComponentSample
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.C ...
- 异步编程设计模式 - IronPythonDebugger
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsof ...
- [.net 多线程]异步编程模式
.NET中的异步编程 - EAP/APM 从.NET 4.5开始,支持的三种异步编程模式: 基于事件的异步编程设计模式 (EAP,Event-based Asynchronous Pattern) 异 ...
- 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程
额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...
- .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)
本文内容 异步编程类型 异步编程模型(APM) 参考资料 首先澄清,异步编程模式(Asynchronous Programming Patterns)与异步编程模型(Asynchronous Prog ...
- C#秘密武器之异步编程
一.概述 1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库.异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某个操作时,应用程序 ...
- [.NET] 怎样使用 async & await 一步步将同步代码转换为异步编程
怎样使用 async & await 一步步将同步代码转换为异步编程 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6079707.html ...
- 多线程之异步编程: 经典和最新的异步编程模型,async与await
经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...
- 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换
经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...
随机推荐
- zlog小试(C语言日志工具)
test.c #include <stdio.h> #include "zlog.h" int main(int argc, char** argv) { int rc ...
- 自制单片机之六……串行I2C总线E2PROM AT24CXXX的应用
这一篇介绍I2C存储器的使用.主要是介绍AT24CXX系列器件,它分为两类,主要是通过被存储容量地址来分的,一类是AT24C02-AT24C16,它的存储容量从256字节到2048字节.另一类是AT2 ...
- AIX和Linux中wtmp的不同处理方式
wtmp 记录用户登录和退出事件.它和utmp日志文件相似,但它随着登陆次数的增加,它会变的越来越大,有些系统的ftp访问也在这个文件里记录,同时它也记录正常的系统退出时间,可以用ac和last命令访 ...
- Struts2标签库之iterator
传说中的第一种方式,这种在Struts2.1权威指南的例子中也木有说明白: <%@ page language="java" contentType="text/h ...
- JS实现 鼠标放上去 图片自动放大的效果
前段时间做项目,要实现,一张图片,鼠标放上去图片自动变大的效果,虽然难度不大,但当时也想了一段时间,当时没时间记录一下,现在有时间了,写篇博客把代码给记录一下: 效果如下: 代码如下: <!DO ...
- cf493C Vasya and Basketball
C. Vasya and Basketball time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- phpcms:六、频道页(category.html)
1.当前栏目的ID:{$catid}标题样式:{title_style($v[style])}(在添加内容或编辑内容的时候,标题右边 有一个选择颜色的块).{str_cut(strip_tags($v ...
- <PHP>字符串处理代码
字符串处理: strlen("aaa");取字符串的长度 *** strcmp("aaa","aaa");比较两个字符串 ...
- hdu 5410 CRB and His Birthday(混合背包)
Problem Description Today is CRB's birthday. His mom decided to buy many presents for her lovely son ...
- Android Studio编译好的apk放在哪里?
Eclipse中编译好的apk文件时在bin文件中面的,可是在Android Studio有一个比較大的修改了,编译好的apk在android studio里面是直接看不到了,并且apk文件所在文件夹 ...