BegainInvoke 和EndInvoke
1、BegainInvoke 从线程池中获取一个线程,并且让引用方法在新的线程中运行。
2、BegainInvoke 返回给调用线程一个IAsyncResult接口的对象的引用。这个接口引用包含了在线程池中运行的异步方法的当前状态,原始线程然后可以继续运行。
3、EndInvoke 方法用来获取有异步方法调用返回的值。并且释放线程所用的资源。
EndInvoke 有以下的特性。
接受一个由BegainInvoke方法返回的IAsyncResult对象的引用,并找到它关联的线程。
如果线程池里面的线程退出了,会做以下的事情。
清理退出的线程的状态并释放其资源。
找到引用方法的返回值并作为其返回值
如果调用的线程池里面的线程还在运行,调用线程就会停止并等待。直到清理完毕并由返回值。
EndInvoke 是为开启的线程进行清理。所以确保每一个BegainInvoke 都会调用EndInvoke。
如果EndInvoke 出现异常。则会抛出异常。
异步编程模式有三种模式
(1)等待到一直结束
delegate long Mysum(int frist, int second);
class Program
{
static void Main(string[] args)
{
Mysum mysum = new Mysum(Sum);
Console.WriteLine("Before BegainInvoke");
IAsyncResult iar = mysum.BeginInvoke(3, 5, null, null);//开始异步调用
Console.WriteLine("After BegainInvoke");
Console.WriteLine("Doing Stuff");
long Result = mysum.EndInvoke(iar);//等待结束并返回结果。
Console.WriteLine("After EndInvoke:{0}", Result);
Console.ReadLine();
}
static long Sum(int x,int y)
{
Console.WriteLine(" inside sum");
Thread.Sleep(10000);
return x + y;
}
}
IAsyncResult 接口被AsyncResult对象包含,AsyncResult类表现为异步的状态。
BegainInvoke 方法调用时时,系统会创建一个AsyncResult 对象。不会返回类对象的引用,而是返回对象中包含IAsyncResult接口的引用。
AsyncResult 对象包含Asyncdelegate属性,它返回一个指向被调用来开启异步方法的委托的引用。这个属性时类的一部分,不是接口的一部分。
IsCompleted 属性返回一个布尔值,表示异步是否完成。
AsyncState属性返回一个对象的引用。作为BegainInvoke方法调用时State的参数。返回是一个Object类型的引用。

2、循环模式
循环模式在判断IAsyncResult中的IsCompleted 是否为True,如果一直为false,则处理循环内的事情,如果TRUE 则返回主线程中去。
代码如下
////// 异步委托的循环模式 /// /// static void Main(string[] args) { Mysum mysum = new Mysum(Sum); Console.WriteLine("Before BegainInvoke"); IAsyncResult iar = mysum.BeginInvoke(3, 5, null, null);//开始异步调用 Console.WriteLine("After BegainInvoke"); while (!iar.IsCompleted) { Console.WriteLine("Not Done"); for (int i = 0; i < 1000000; i++) { Console.WriteLine($"{i}"); if (iar.IsCompleted) { break; } } } Console.WriteLine("Done"); long Result = mysum.EndInvoke(iar);//等待结束并返回结果。 Console.WriteLine("After EndInvoke:{0}", Result); Console.ReadLine(); } static long Sum(int x, int y) { Console.WriteLine(" inside sum"); Thread.Sleep(100); return x + y; }
3、回调模式,回调模式不回阻塞线程。而一直等待模式,循环模式,也会存在阻塞线程,而回调模式不存在阻塞线程。BegainInvoke 开始异步线程后,立即返回主线程,结果由回调函数处理。
理论
回调方法的签名和返回参数必须跟AsyncCallback 委托类型所描述的一致。它需要方法接受一个IAsyncResult 作为参数,并且返回参数为Void
案例如下
static void Main(string[] args)
{
Mysum summ = new Mysum(Sum);
Console.WriteLine("Before BegainInvoke");
IAsyncResult iar = summ.BeginInvoke(5, 2, new AsyncCallback(CallWhenDone), null);
Console.WriteLine("Doing more work in Main");
Thread.Sleep(500);
Console.WriteLine("Doing with Main.Exting");
Console.ReadLine();
}
//回调函数
static void CallWhenDone(IAsyncResult iar)
{
Console.WriteLine(" inside CallWhenDone");
AsyncResult ar = (AsyncResult)iar;//显示转换为AsyncResult类。
Mysum sums=(Mysum)ar.AsyncDelegate;//返回一个指向被调用来开启异步方法的委托的引用
long result = sums.EndInvoke(iar);
Console.WriteLine(" The result is {0}", result);
}
//委托方法
static long Sum(int x,int y)
{
Console.WriteLine(" inside sum");
Thread.Sleep(100);
return x + y;
}

浙公网安备 33010602011771号