使用BeginInvoke和EndInvoke进行异步调用的四种常用方法,每种方法都是通过BeginInvoke方法来启动异步方法,调用EndInvoke方法来完成异步调用。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
public delegate void AsynComputeCaller( int num, out int result);
class Factorial
{
public int Compute( int num)
{
Thread.Sleep( new Random().Next( 100 , 999 ));
if (num == 1 ) return 1 ;
return num * this .Compute(num - 1 );
}
/// <summary>
/// 异步计算阶乘
/// </summary>
/// <param name="num"></param>
/// <param name="result"></param>
public void AsynCompute( int num, out int result)
{
Console.WriteLine( " \n AsynCompute...start " );
DateTime startTime = DateTime.Now;
result = this .Compute(num);
DateTime endTime = DateTime.Now;
Console.WriteLine( " \n AsynCompute...end(Milliseconds Used:{0}) " ,
endTime.Subtract(startTime).Milliseconds);
}
}
class Program
{
int result = 0 ;
/// <summary>
/// 调用BeginInvoke方法启动异步方法,
/// 进行某些操作,
/// 然后调用EndInvoke方法来一直阻止请求线程到调用完成。
/// </summary>
void Run()
{
Factorial f = new Factorial();
AsynComputeCaller caller = new AsynComputeCaller(f.AsynCompute);
Console.WriteLine( " Run...start " );
IAsyncResult iAsyncResult = caller.BeginInvoke( 4 , out result, null , null );
// 主线程进行一些操作
Console.WriteLine( " 主线程进行一些操作 " );
for ( int i = 0 ; i < 50 ; i ++ )
{
Thread.Sleep( 50 );
Console.Write( " . " );
}
Console.WriteLine();
// 调用EndInvoke来等待异步调用结束,并获得结果
caller.EndInvoke( out result, iAsyncResult);
Console.Write( " Run...end(result:{0}) " , result);
}
/// <summary>
/// 调用BeginInvoke方法启动异步方法,
/// 使用System.IAsyncResult.AsyncWaitHandle属性获取WaitHandle,
/// 使用它的WaitOne方法一直阻止执行直到发出WaitHandle信号,
/// 然后调用EndInvoke方法。
/// </summary>
void Run2()
{
Factorial f = new Factorial();
AsynComputeCaller caller = new AsynComputeCaller(f.AsynCompute);
Console.WriteLine( " Run...start " );
IAsyncResult iAsyncResult = caller.BeginInvoke( 12 , out result, null , null );
// 主线程进行一些操作
Console.WriteLine( " 主线程进行一些操作 " );
for ( int i = 0 ; i < 50 ; i ++ )
{
Thread.Sleep( 50 );
Console.Write( " . " );
}
Console.WriteLine();
Console.WriteLine( " 等待WaitHandle接收到信号 " );
// 等待WaitHandle接收到信号
iAsyncResult.AsyncWaitHandle.WaitOne();
caller.EndInvoke( out result, iAsyncResult);
Console.Write( " Run...end(result:{0}) " , result);
}
/// <summary>
/// 调用BeginInvoke方法启动异步方法,
/// 轮询由BeginInvoke返回的IAsyncResult,
/// 确定异步调用何时完成,
/// 然后调用EndInvoke。
/// </summary>
void Run3()
{
Factorial f = new Factorial();
AsynComputeCaller caller = new AsynComputeCaller(f.AsynCompute);
Console.WriteLine( " Run...start " );
IAsyncResult iAsyncResult = caller.BeginInvoke( 6 , out result, null , null );
// 主线程进行一些操作
Console.WriteLine( " 主线程进行一些操作 " );
while ( ! iAsyncResult.IsCompleted)
{
Thread.Sleep( 100 );
Console.Write( " . " );
}
Console.WriteLine();
Console.WriteLine( " 异步方法已经结束 " );
// 等待WaitHandle接收到信号
iAsyncResult.AsyncWaitHandle.WaitOne();
caller.EndInvoke( out result, iAsyncResult);
Console.Write( " Run...end(result:{0}) " , result);
}
/// <summary>
/// 调用BeginInvoke方法启动异步方法时,
/// 将代表异步方法完成时需要回调的方法的委托传递给BeginInvoke。
/// 异步调用完成后,将在ThreadPool线程上执行该回调方法。
/// 在该回调方法中调用EndInvoke。
/// </summary>
void Run4()
{
Factorial f = new Factorial();
AsynComputeCaller caller = new AsynComputeCaller(f.AsynCompute);
Console.WriteLine( " Run...start " );
IAsyncResult iAsyncResult = caller.BeginInvoke( 6 , out result,
new AsyncCallback(CallbackMethod), caller);
// 主线程进行一些操作
Console.WriteLine( " 主线程进行一些操作 " );
for ( int i = 0 ; i < 50 ; i ++ )
{
Thread.Sleep( 50 );
Console.Write( " . " );
}
Console.WriteLine();
}
void CallbackMethod(IAsyncResult ar)
{
AsynComputeCaller caller = (AsynComputeCaller)ar.AsyncState;
caller.EndInvoke( out result, ar);
Console.Write( " Run...end(result:{0}) " , result);
}
static void Main( string [] args)
{
Program p = new Program();
Console.WriteLine( " \n\n*** Run *** " );
p.Run();
Console.WriteLine( " \n\n*** Run2 *** " );
p.Run2();
Console.WriteLine( " \n\n*** Run3 *** " );
p.Run3();
Console.WriteLine( " \n\n*** Run4 *** " );
p.Run4();
Console.Read();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
public delegate void AsynComputeCaller( int num, out int result);
class Factorial
{
public int Compute( int num)
{
Thread.Sleep( new Random().Next( 100 , 999 ));
if (num == 1 ) return 1 ;
return num * this .Compute(num - 1 );
}
/// <summary>
/// 异步计算阶乘
/// </summary>
/// <param name="num"></param>
/// <param name="result"></param>
public void AsynCompute( int num, out int result)
{
Console.WriteLine( " \n AsynCompute...start " );
DateTime startTime = DateTime.Now;
result = this .Compute(num);
DateTime endTime = DateTime.Now;
Console.WriteLine( " \n AsynCompute...end(Milliseconds Used:{0}) " ,
endTime.Subtract(startTime).Milliseconds);
}
}
class Program
{
int result = 0 ;
/// <summary>
/// 调用BeginInvoke方法启动异步方法,
/// 进行某些操作,
/// 然后调用EndInvoke方法来一直阻止请求线程到调用完成。
/// </summary>
void Run()
{
Factorial f = new Factorial();
AsynComputeCaller caller = new AsynComputeCaller(f.AsynCompute);
Console.WriteLine( " Run...start " );
IAsyncResult iAsyncResult = caller.BeginInvoke( 4 , out result, null , null );
// 主线程进行一些操作
Console.WriteLine( " 主线程进行一些操作 " );
for ( int i = 0 ; i < 50 ; i ++ )
{
Thread.Sleep( 50 );
Console.Write( " . " );
}
Console.WriteLine();
// 调用EndInvoke来等待异步调用结束,并获得结果
caller.EndInvoke( out result, iAsyncResult);
Console.Write( " Run...end(result:{0}) " , result);
}
/// <summary>
/// 调用BeginInvoke方法启动异步方法,
/// 使用System.IAsyncResult.AsyncWaitHandle属性获取WaitHandle,
/// 使用它的WaitOne方法一直阻止执行直到发出WaitHandle信号,
/// 然后调用EndInvoke方法。
/// </summary>
void Run2()
{
Factorial f = new Factorial();
AsynComputeCaller caller = new AsynComputeCaller(f.AsynCompute);
Console.WriteLine( " Run...start " );
IAsyncResult iAsyncResult = caller.BeginInvoke( 12 , out result, null , null );
// 主线程进行一些操作
Console.WriteLine( " 主线程进行一些操作 " );
for ( int i = 0 ; i < 50 ; i ++ )
{
Thread.Sleep( 50 );
Console.Write( " . " );
}
Console.WriteLine();
Console.WriteLine( " 等待WaitHandle接收到信号 " );
// 等待WaitHandle接收到信号
iAsyncResult.AsyncWaitHandle.WaitOne();
caller.EndInvoke( out result, iAsyncResult);
Console.Write( " Run...end(result:{0}) " , result);
}
/// <summary>
/// 调用BeginInvoke方法启动异步方法,
/// 轮询由BeginInvoke返回的IAsyncResult,
/// 确定异步调用何时完成,
/// 然后调用EndInvoke。
/// </summary>
void Run3()
{
Factorial f = new Factorial();
AsynComputeCaller caller = new AsynComputeCaller(f.AsynCompute);
Console.WriteLine( " Run...start " );
IAsyncResult iAsyncResult = caller.BeginInvoke( 6 , out result, null , null );
// 主线程进行一些操作
Console.WriteLine( " 主线程进行一些操作 " );
while ( ! iAsyncResult.IsCompleted)
{
Thread.Sleep( 100 );
Console.Write( " . " );
}
Console.WriteLine();
Console.WriteLine( " 异步方法已经结束 " );
// 等待WaitHandle接收到信号
iAsyncResult.AsyncWaitHandle.WaitOne();
caller.EndInvoke( out result, iAsyncResult);
Console.Write( " Run...end(result:{0}) " , result);
}
/// <summary>
/// 调用BeginInvoke方法启动异步方法时,
/// 将代表异步方法完成时需要回调的方法的委托传递给BeginInvoke。
/// 异步调用完成后,将在ThreadPool线程上执行该回调方法。
/// 在该回调方法中调用EndInvoke。
/// </summary>
void Run4()
{
Factorial f = new Factorial();
AsynComputeCaller caller = new AsynComputeCaller(f.AsynCompute);
Console.WriteLine( " Run...start " );
IAsyncResult iAsyncResult = caller.BeginInvoke( 6 , out result,
new AsyncCallback(CallbackMethod), caller);
// 主线程进行一些操作
Console.WriteLine( " 主线程进行一些操作 " );
for ( int i = 0 ; i < 50 ; i ++ )
{
Thread.Sleep( 50 );
Console.Write( " . " );
}
Console.WriteLine();
}
void CallbackMethod(IAsyncResult ar)
{
AsynComputeCaller caller = (AsynComputeCaller)ar.AsyncState;
caller.EndInvoke( out result, ar);
Console.Write( " Run...end(result:{0}) " , result);
}
static void Main( string [] args)
{
Program p = new Program();
Console.WriteLine( " \n\n*** Run *** " );
p.Run();
Console.WriteLine( " \n\n*** Run2 *** " );
p.Run2();
Console.WriteLine( " \n\n*** Run3 *** " );
p.Run3();
Console.WriteLine( " \n\n*** Run4 *** " );
p.Run4();
Console.Read();
}
}
}