












APM(Asynchronous Programming Model),异步编程模型。
大家对这个应该不会陌生,甚至太过于熟悉了吧!因为在太多的地方看到过它,对于应用上也许更没的说了!呵呵。
Control:BeginInvoke、EndInvoke
Stream:BeginWrite、EndWrite
......
上面这些都是FCL已经提供的可以使用APM的类,不过可能在一些特定的情况下:
1、构建和一些硬件(FCL没有提供支持的)直接交互的类。
2、BeginXXX、EndXXX这些都不是相同的名称,希望让调用者使用起来更加简单,对于这些现有的异步类进行下抽象。
3、在自定义的类上执行某些方法也许需要很多的时间,这些希望对这些方法进行异步处理,所以也加上APM这种方式。
4、一些Win32的函数(Win32注册表、日志...)目前只提供了同步处理,所以当使用这些的时候,希望对这些函数做些封装,加上异步支持。
............
相信大家现在都明白为什么要自己的APM了吧!OK,那就让我们开始吧!
APM的核心(IAsyncResult)
IAsyncResult接口是APM机制的核心:
public interface IAsyncResult {
WaitHandle AsyncWaitHandle { get; } // For Wait-Until-Done technique
Boolean IsCompleted { get; } // For Polling technique
Object AsyncState { get; } // For Callback technique
Boolean CompletedSynchronously { get; } // Almost never used
}
当任何一个BeginXXX方法被调用的时候,都会返回一个继承于该接口的对象。该对象可以用来监视异步动作的执行,例如,当调用BeginXXX后,我们可以通过该对象的属性判断异步动作是否完成,同时如果异步执行的时候有异常,那么就会将异常信息传给EndXXX方法,EndXXX方法等待异步动作执行完成后,将异常抛出。
AsyncResultNoResult类继承于IAsyncResult接口,该类用于无特殊返回值的异步动作(执行成功或失败),例如stream的BeginWrite、EndWrite。
public override void EndWrite(IAsyncResult asyncResult)AsyncResultNoResult类:
Code
Code
利用自定义的IAsyncResult实现APM
Code
Code
执行结果如下:

2、比较自定义APM和delegate之间的性能
Code
执行结果如下:
![]()
从结果上看,既然自定义的APM性能要比FCL的APM好点,其实在这里大家仔细看下就可以清楚:
区别就在于ManualResetEvent,FCL的APM是在创建IAsyncResult对象的同时,也创建了ManualResetEvent。而AsyncResultNoResult中,可以看下面的代码,只有在真正需要用到ManualResetEvent的时候,才去创建,一般不实例化。有个注意的地方:ManualResetEvent是内核对象,而创建或使用一个内核对象都是很耗资源的,所以只有当真正需要的时候才去使用。
public WaitHandle AsyncWaitHandle
{
get
{
if (m_AsyncWaitHandle == null)
{
Boolean done = IsCompleted;
ManualResetEvent mre = new ManualResetEvent(done);
if (Interlocked.CompareExchange(ref m_AsyncWaitHandle,
mre, null) != null)
{
mre.Close();
}
else
{
if (!done && IsCompleted)
{
m_AsyncWaitHandle.Set();
}
}
}
return m_AsyncWaitHandle;
}
参考Jeffrey Richter的
http://msdn.microsoft.com/en-us/magazine/cc163467.aspx此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。