shangxijie

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
from:http://elvewyn.spaces.live.com/blog/cns!c4ba10adacae3203!496.entry
 
要想异步的调用一个方法,首先就要实现该方法啦。比如,方法的如下:
        public class Test{
            public string TestMethod(int param, out int param2){
                //一些操作
            }
        }
    方法实现的时候需要注意的就是方法要设计为线程安全的。因为异步调用其实就是多线程。
    然后,声明一个委托(Delegate)。这将是异步调用的关键。比如这个委托是这么声明的:
        public delegate string AsyncTestMethod(int param, out int param2);
    再然后呢,我们就可以通过委托对TestMethod进行异步调用了。
    首先,实例化Test类:
        Test t = new Test();
    然后,实例化一个委托: 
        AsyncTestMethod atm = new AsyncTestMethod(t.TestMethod);
接着,只需要调用这个委托对象的BeginInoke方法。就可以将这个方法放到一个单独的线程中运行了:
        IAsyncResult ar = atm.BeginInvoke(100, y, null, null);
 
IAsyncResult ar = atm.BeginInvoke(100, y, null, null);
    BeginInvoke方法有很多参数而且是个数不定的。最前面的几个,就是被委托方法的参数。在这个例子中,前面两个,就是int param和out int param2两个参数。最后两个参数和返回值。一会儿再说。
    调用完BeginInvoke,TestMethod方法被放入其他的线程中执行。这个时候,主线程(相对于TestMethod的执行线程)可以继续往下执行。坐一些其他的工作。与TestMethod并行的执行。然后,调用委托的EndInvoke方法。
String result = atm.EndInvoke(y, ar);
    EndInvoke方法会一个阻塞当前线程的执行,直到委托方法执行完毕。这个方法的签名也是不定的。MSDN中对于该方法签名规则的说明是:
  • 包括所有 IN/OUT 参数。
  • 包括所有 OUT 参数。
  • 包括所有 ByRef 参数。
  • IAsyncResult 作为最后一个参数。
  • 从原始方法签名返回原始返回类型。

    通过EndInvoke方法执行完,就意味着被委托方法已经执行完毕。在本例中,result为方法的返回值。y为前面那个out 参数。至此,一个简单的异步调用完成了。

当然,异步调用到此肯定还没有介绍完。在调用BeginInvoke方法的时候,该方法返回了一个实现了IAsyncResult接口的对象。使用该对象可以监视和管理异步操作。例如,这个接口有一个IsComplete的属性。我们可以通过这个属性的值来判定方法是否已经执行完毕。如果以处理完调用,该属性的值就为True。

    在前面,BeginInvoke方法最后一个参数。我们可以随便传一个Object的对象进去。这个对象就可以从IAsyncResult对象的AsyncState属性取出来。我们可以把与该方法调用相关的一些上下文对象放在这里。以便以后方法调用完成的时候使用。这种模式主要用于异步调用完毕后的回调。这些将在稍后进行介绍。

    当然IAsyncResult接口的属性还不止这些。有兴趣或者需求的还可以看一下MSDN中更为详尽的解释。

刚才说到了“回调”。回调就是说当方法执行完毕后,自动继续调用一个其他的方法。这个多少有些事件订阅的意思。在设计模式中应该叫做“观察者模式”吧。例如,当我们异步调用一个复制文件的方法。调用开始后,我们的程序可以给用户继续显示复制的进度、播放一首歌或者让用户选择更多其他的操作。当操作完成的时候,程序自动调用一个方法来通过视觉或者听觉回馈给用户:操作已经完成了。这时候,也许使用“回调”是个不错的选择。

    要实现回调。就要用的BeginInvoke倒数第二个参数。该参数接收的类型是AsyncCallback——一个回调方法的委托。这个委托的签名是这个样子的:

    public delegate void AsyncCallback(IAsyncResult ar);

    所以,在这个例子中,我们需要实现一个被回调的方法。我们把这个方法放在Test类中——当然,放在其他的类中也可以:

    public void OnFinished(IAsyncResult ar){

        //操作完成后的动作

    }

    调用BeginInvoke的时候需要注意以下最后两个参数:

        IAsyncResult ar = t.BeginInvoke(200, y,  new AsyncCallback(t.OnFinished), t);

    然后呢?然后就等着方法执行完毕吧。我们的主线程可以撒开手不去管了。当调用完毕后,OnFinished方法就会自动登场来进行后续的处理。

    在OnFinished方法中,我们可以用通过参数取得IAsyncResult接口的对象。然后通过AsyncState属性得到一个Object对象。这就是我们在BeginInvoke最后一个参数中传进去的那个东西。在这个例子中,我们传进去的是那个委托的对象。在这里,我们就可以像前面那样调用委托的EndInvoke方法取到方法执行的结果。完成操作了。

    这些大概就是C#中的异步调用了。其实说了这么多,还只是一些皮毛。更具体的内容,还是去MSDN中查吧。

posted on 2008-06-10 21:52  尚希杰  阅读(503)  评论(1编辑  收藏  举报