借用msdn的例子,说明.NET中异步委托的使用。
样例中给出了异步委托调用常用的两种方法,一是采用回调函数AsyncCallback+线程同步ManualResetEvent,另一是使用IAsyncResult的IsCompleted属性。调用异步委托的关键在线程间的同步及参数的传递,下面说一下两种方法的一般步骤。
1.采用回调函数AsyncCallback
a. Factorize,实体函数,就是实际调用的作计算用的函数;
b. AsyncFactorCaller,委托,跟实体函数的定义要一致,参数及返回值;
c. FactorizedResults,回调函数,就是处理计算结果的函数;
d. ManualResetEventwaiter,线程同步;
具体使用
AsyncFactorCallerfactorDelegate = new AsyncFactorCaller(PrimeFactorFinder.Factorize);//定义委托
AsyncCallbackcallBack = new AsyncCallback(this.FactorizedResults);//定义回调函数
IAsyncResultresult = factorDelegate.BeginInvoke(
number,
ref temp,
ref temp,
callBack,
number); //调用委托;
waiter.WaitOne();//等待处理结束
2.采用IAsyncResult的IsCompleted属性
a. Factorize,实体函数,就是实际调用的作计算用的函数;
b. AsyncFactorCaller,委托,跟实体函数的定义要一致,参数及返回值;
具体使用
AsyncFactorCallerfactorDelegate = new AsyncFactorCaller(PrimeFactorFinder.Factorize);// 定义委托
IAsyncResultresult = factorDelegate.BeginInvoke(
number,
ref temp,
ref temp,
null,
null); //调用委托;
while (!result.IsCompleted)//等待调用结束
{
// Do any work you can do before waiting.
result.AsyncWaitHandle.WaitOne(10000, false);
}
result.AsyncWaitHandle.Close();
//处理调用的结果
int factor1=0;
int factor2=0;
// Obtain the result.
bool answer = factorDelegate.EndInvoke(ref factor1, ref factor2, result);
附msdn代码:
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
namespaceExamples.AdvancedProgramming.AsynchronousOperations
{
// Create a class that factors a number.
public class PrimeFactorFinder
{
public static bool Factorize(
int number,
ref int primefactor1,
ref int primefactor2)
{
primefactor1 = 1;
primefactor2 = number;
// Factorize using a low-tech approach.
for (int i=2;i<number;i++)
{
if (0 == (number % i))
{
primefactor1 = i;
primefactor2 = number / i;
break;
}
}
if (1 == primefactor1 )
return false;
else
return true ;
}
}
// Create an asynchronous delegate that matches the Factorize method.
public delegate bool AsyncFactorCaller(
int number,
ref int primefactor1,
ref int primefactor2);
public class DemonstrateAsyncPattern
{
// The waiter object used to keep the mainapplication thread
// from terminating before the callbackmethod completes.
ManualResetEvent waiter;
// Define the method that receives a callbackwhen the results are available.
public voidFactorizedResults(IAsyncResult result)
{
int factor1=0;
int factor2=0;
// Extract the delegate from the
//System.Runtime.Remoting.Messaging.AsyncResult.
AsyncFactorCaller factorDelegate= (AsyncFactorCaller)((AsyncResult)result).AsyncDelegate;
int number = (int) result.AsyncState;
// Obtain the result.
bool answer = factorDelegate.EndInvoke(ref factor1, ref factor2, result);
// Output the results.
Console.WriteLine("On CallBack: Factors of {0} : {1}{2} - {3}",
number, factor1, factor2,answer);
waiter.Set();
}
// The following method demonstrates theasynchronous pattern using a callback method.
public voidFactorizeNumberUsingCallback()
{
AsyncFactorCaller factorDelegate = new AsyncFactorCaller(PrimeFactorFinder.Factorize);
int number = 1000589023;
int temp=0;
// Waiter will keep the main applicationthread from
// ending before the callback completesbecause
// the main thread blocks until the waiter issignaled
// in the callback.
waiter = new ManualResetEvent(false);
// Define the AsyncCallback delegate.
AsyncCallback callBack = new AsyncCallback(this.FactorizedResults);
// Asynchronously invoke the Factorizemethod.
IAsyncResult result =factorDelegate.BeginInvoke(
number,
ref temp,
ref temp,
callBack,
number);
// Do some other useful work while
// waiting for the asynchronous operation tocomplete.
// When no more work can be done, wait.
waiter.WaitOne();
}
// The following method demonstrates theasynchronous pattern
// using a BeginInvoke, followed by waitingwith a time-out.
public voidFactorizeNumberAndWait()
{
AsyncFactorCaller factorDelegate = new AsyncFactorCaller(PrimeFactorFinder.Factorize);
int number = 1000589023;
int temp=0;
// Asynchronously invoke the Factorizemethod.
IAsyncResult result =factorDelegate.BeginInvoke(
number,
ref temp,
ref temp,
null,
null);
while(!result.IsCompleted)
{
// Do any work you can do before waiting.
result.AsyncWaitHandle.WaitOne(10000, false);
}
result.AsyncWaitHandle.Close();
// The asynchronous operation has completed.
int factor1=0;
int factor2=0;
// Obtain the result.
bool answer = factorDelegate.EndInvoke(ref factor1, ref factor2, result);
// Output the results.
Console.WriteLine("Sequential : Factors of {0} : {1}{2} - {3}",
number, factor1,factor2, answer);
}
public static void Main()
{
DemonstrateAsyncPattern demonstrator= new DemonstrateAsyncPattern();
demonstrator.FactorizeNumberUsingCallback();
demonstrator.FactorizeNumberAndWait();
}
}
}