APM(Asynchrocous Programming Model)方式:
通过委托类异步调用方法:
1.定义一个委托类型:
delegate int MyDeletateType(string s);
2.实例化一个委托实例,构造时候传入需要异步调用的函数FuncA
var del = new MyDeletateType(FuncA);
int FuncA(string a)
{
Console.WriteLine(a);
return 1;
}
或者
var del = new MyDeletateType((a)=> {Console.WriteLine(a);return 1;});
3.通过委托异步调用方法:
del.BeginInvoke("hello", null, null);
4.上述方法是 IAsyncResult BeginInvoke(string s,AsyncCallback callback,object @object)
string s对应异步调用的函数FunA的入参,AsyncCallback callback是回调函数的委托实例,object @object是用户自定义的参数,该参数存放在IAsyncResult ar中的AsyncState中;
其中用于回调函数的委托实例是
public delegate void AsyncCallback(IAsyncResult ar);
BeginInvoke调用后 会马上返回IAsyncResult,同时异步调用函数FuncA。FuncA完成后,调用回调函数,回调函数中入参是同一份的IAsyncResult.
则:
如果需要向回调函数传入参数,可以使用BeginInvoke中的object参数,此参数存放在IAsyncResult .AsyncState中,回调函数中可以获取此参数,由于IAsyncResult .AsyncState 只读,回调函数对该参数不作修改。(若object存入的是引用类型,则可修改实例对象内容)
调用BeginInvoke方法后返回IAsyncResult ,
可以使用IsCompleted:bool判断异步方法是否完成,异步方法完成后,则该标志位为true,然后开始调用回调函数。
可以使用AsyncWaitHandle.WaitOne() 等待异步调用的方法完成。完成后WaitOne返回True;有重载函数WaitOne(Timespan timeOut)等方法,指定等待一定时间,如果时间范围内异步方法执行完成,则马上返回true,如果设定时间范围内,异步方法未完成,则返回false.
因此:
可以使用轮询IsCompleted属性的方法,及WaitOne()的方法判断异步方法是否完成。
最后,调用方调用异步方法后如何能获取异步方法的返回值呢。可以使用MyDelegate中的int EndInvoke(IAsyncResult ar)方法。
var del = new MyDeletateType((a) => { Console.WriteLine(a); return 1; });
var asyncResult = del.BeginInvoke("hello", null, null);
var result = del.EndInvoke(asyncResult);
EndInvoke方法等待异步方法完成及返回异步方法返回的结果。
APM的缺点是
1.调用后无法取消异步方法的执行
2.调用后不知道异步方法执行的进度
3.异步方法在另一条线程中执行,和调用方的线程非同一条线程。有时候会引起线程安全的问题。
为了解决这些问题,微软推出了其他的异步模式。