关于异步模式
从代码角度来解释,是指在异步操作执行模式下,各语句执行结束的顺序与语句执行开始的顺序并不一定相同。举个例子来说:一个插入操作,代码执行到具有异步插入函数特性的代码行后,将马上执行下一行代码,而不会去等待数据库插入完成之后才进行下一步。
异步模式是如何工作的
实际上我们开发的软件绝大多数都运行在多任务管理的操作系统上,CUP将把请求的任务分成若干多个任务片断,所以不可能出现两个任务同时出现工作的事情出现,而你能一边写博客一边听音乐,这种人们感觉上同时工作的状态其实是一种幻觉。
就我认为的在.Net下使用异步操作是通过线程阻塞的方式实现的。举例来说:当一个主调线程工作运行时,在遇到一个异步回 调函数时,主线程不阻塞而直接执行下面的逻辑,与此同时,系统将会启动另一个线程去执行异步回调函数(该回调函数可能会利用某种机制锁住),当回调函数操 作结束后会利用某种方式通知主线程任务完成可以对该函数运行产生的结果进行下面的操作了。
什么情况下使用异步模式
1、在负荷很重的客户/服务器系统中,适宜采用异步执行模式.在这种环境下,时间延迟频繁且漫长,相比之下异步执行的开销 微不足道。
2、在多数据库存储不同业务数据的系统中适合使用异步模式。模拟的适用场景:假设您需要在应用程序中显示有关特定员工的信 息,但该信息的一部分位于人力资源数据库中,而与薪资有关的信息位于会计数据库中。如果能够同时向两个数据库发送查询并让二者并行执行,而不是在启动第二 个语句之前先等待第一个语句完成。
使用异步模式在大多数情况下会使你开发的应用程序性能得到一定程度上的提高。
委托
委托是一种引用类型而不是方法。用微软的话说:“在C或C++ 中与委托最为相似的是函数指针。然而,函数指针只能引用静态函数,而委托可以引用静态方法和实例方法。当委托引用实例方法时,委托不仅存储对方法入口点的 引用,还存储对为其调用该方法的类实例的引用。与函数指针不同,委托是面向对象和类型安全的。”
下面对.Net的委托进行代码剖析:
委托定义的规则如下:
public delegate void myEventHandler(int i,out string o);
再用MSIL反汇编程序(Ildasm.exe)来观看反汇编代码
其实CLR为我们做了4件事情
1.定义一个构造器
2.定义一个虚方法BeginInvoke
3.定义一个虚方法EndInvoke
4.定义一个虚方法Invoke
(1)在反汇编代码中我看到如下片断:
.class auto ansi sealed nested public myEventHandler
extends [mscorlib]System.MulticastDelegate
{
} // end of class myEventHandler
由此可以知道其实我们声明的委托myEventHandler就是一个密封类
正因为委托是一个类,所以委托在类内和类外都是可以定义的。
(2)我们现在再来看看构造器
在这之前,有必要搞清楚委托的继承关系
System.Delegate
---System.MulticastDelegate
------ConsoleApplication1.myEventHandler
现在我们实例化一个委托:
myEventHandler my=new myEventHandler(staticCall);
实际上它是在调用这个委托的构造器
下面的是这个构造器的代码:
public myEventHandler(object @object, IntPtr method);
第一个参数应该是类实例的实例
第二个参数应该是委托的方法信息
这个构造器会再调用它父类的构造器,父类构造器代码如下:
protected MulticastDelegate(object target, string method) : base(target, method)
{
}
最终调用的是System.Delegate的构造器
protected Delegate(object target, string method)
这个构造器是对类System.Delegate的2个私有字段进行处理
private object _target;
private RuntimeMethodInfo _method;
System.Delegate类有2个公有属性可以得到上述2个私有字段的数值:
1.Method
获取委托所表示的方法
2.Target
获取类实例,当前委托将对其调用实例方法
如果是静态方法,则为空引用
下面是效果代码
class Program
{
private delegate void myEventHandler(int i,out string o);
static void Main(string[] args)
{
Program p = new Program();
myEventHandler my = new myEventHandler(staticCall);
if (my.Target == null)
{
Console.WriteLine("我们调用的类静态方法!");
}
else
{
Console.WriteLine("我们调用的类静态名称为:"+my.Target.ToString());
}
MemberInfo info = my.Method; //MemberInfo从属于System.Reflection命名空间下
Console.WriteLine("此方法的基于信息:"+my.Method.ToString());
Console.WriteLine(my.Method.IsStatic?"此方法是一个静态方法":"此方法是一个实例方法");
Console.WriteLine("此方法的名称为:"+info.Name);
Console.ReadLine();
}
public void call(int i, out string o)
{
o = "hello world!";
}
public static void staticCall(int i, out string o)
{
o = "hello world!";
}
}
显示结果为:
我们调用的类静态方法
此方法的基本信息:Void staticCall(Int32,System.String ByRef)
此方法是一个静态方法
此方法的名称为staticCall
将代码中加粗的那一行改成myEventHandler my=new myEventHandler(p.call);
则将会得到这样的结果
我们调用的实例名称为:ConsoleApplication1.Program
此方法的基本信息:Void call(Int32,System.String ByRef)
此方法是一个实例方法
此方法的名称为call
(3)委托的虚方法BeginInvoke和虚方法EndInvoke
它的代码原型如下:
public virtual IAsyncResult BeginInvoke(int i, out string o, AsyncCallback callback, object @object);
public virtual void EndInvoke(out string o, IAsyncResult result);
BeginInvoke 异步方法签名的规则是:
包括所有 IN 参数。
包括所有 OUT 参数。
包括所有 IN/OUT 参数。
包括所有 ByRef 参数。
将 AsyncCallback 和 AsyncState(可通过 IAsyncResult 接口的 AsyncState 属性获得)作为最后两个参数。
返回 IAsyncResult
EndInvoke 异步方法签名的规则是:
包括所有 IN/OUT 参数。
包括所有 OUT 参数。
包括所有 ByRef 参数。
将 IAsyncResult 作为最后一个参数。
这2个方法提供了委托的异步编程方法支持。
(4)委托的方法Invoke
它的签名和委托的签名是一样的,实际上是委托的同步编程方法.
实际上是通过它来回调我们委托的方法。
(5)委托的优点
1、压缩方法的调用。2、合理有效地使用委托能提升应用程序的性能(主要指的是异步牧草做操作)。3、用于调用匿名方法.
参考引用的相关资料:
1、http://www.cnblogs.com/shanyou/articles/345057.html
2、http://zeus.cnblogs.com/archive/2005/12/12/295656.html
来源:http://idai.blogbus.com/logs/8360784.html