使用BeginInvoke和EndInvoke进行异步调用的四种常用方法
使用BeginInvoke和EndInvoke进行异步调用的四种常用方法,每种方法都是通过BeginInvoke方法来启动异步方法,调用EndInvoke方法来完成异步调用。
代码
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();
}
}
}