zoukankan      html  css  js  c++  java
  • delegate BeginInvoke& EndInvoke

    .NET   Framework   允许您异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名的   BeginInvoke   和   EndInvoke   方法。

    BeginInvoke   方法用于启动异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。BeginInvoke   立即返回,不等待异步调用完成。BeginInvoke   返回   IasyncResult,可用于监视调用进度。

    EndInvoke   方法用于检索异步调用结果。调用   BeginInvoke   后可随时调用   EndInvoke   方法;如果异步调用未完成,EndInvoke   将一直阻塞到异步调用完成。EndInvoke   的参数包括您需要异步执行的方法的   out   和   ref   参数(在   Visual   Basic   中为   <Out>   ByRef   和   ByRef)以及由   BeginInvoke   返回的   IAsyncResult。

    注意       Visual   Studio   .NET   中的智能感知功能会显示   BeginInvoke   和   EndInvoke   的参数。如果您没有使用   Visual   Studio   或类似的工具,或者您使用的是   C#   和   Visual   Studio   .NET,请参见异步方法签名获取有关运行库为这些方法定义的参数的描述。
    本主题中的代码演示了四种使用   BeginInvoke   和   EndInvoke   进行异步调用的常用方法。调用了   BeginInvoke   后,可以:  

    进行某些操作,然后调用   EndInvoke   一直阻塞到调用完成。  
    使用   IAsyncResult.AsyncWaitHandle   获取   WaitHandle,使用它的   WaitOne   方法将执行一直阻塞到发出   WaitHandle   信号,然后调用   EndInvoke。  
    轮询由   BeginInvoke   返回的   IAsyncResult,确定异步调用何时完成,然后调用   EndInvoke。  
    将用于回调方法的委托传递给   BeginInvoke。该方法在异步调用完成后在   ThreadPool   线程上执行,它可以调用   EndInvoke。  
    警告       始终在异步调用完成后调用   EndInvoke。
    测试方法和异步委托
    四个示例全部使用同一个长期运行的测试方法   TestMethod。该方法显示一个表明它已开始处理的控制台信息,休眠几秒钟,然后结束。TestMethod   有一个   out   参数(在   Visual   Basic   中为   <Out>   ByRef),它演示了如何将这些参数添加到   BeginInvoke   和   EndInvoke   的签名中。您可以用类似的方式处理   ref   参数(在   Visual   Basic   中为   ByRef)。

    下面的代码示例显示   TestMethod   以及代表   TestMethod   的委托;若要使用任一示例,请将示例代码追加到这段代码中。

    注意       为了简化这些示例,TestMethod   在独立于   Main()   的类中声明。或者,TestMethod   可以是包含   Main()   的同一类中的   static   方法(在   Visual   Basic   中为   Shared)。

    [C#]
    using   System;
    using   System.Threading;  

    public   class   AsyncDemo   {
            //   The   method   to   be   executed   asynchronously.
            //
            public   string   TestMethod(int   callDuration,   out   int   threadId)   {
                    Console.WriteLine( "Test   method   begins. ");
                    Thread.Sleep(callDuration);
                    threadId   =   AppDomain.GetCurrentThreadId();
                    return   "MyCallTime   was   "   +   callDuration.ToString();
            }
    }

    //   The   delegate   must   have   the   same   signature   as   the   method
    //   you   want   to   call   asynchronously.
    public   delegate   string   AsyncDelegate(int   callDuration,   out   int   threadId);

    使用   EndInvoke   等待异步调用
    异步执行方法的最简单方式是以   BeginInvoke   开始,对主线程执行一些操作,然后调用   EndInvoke。EndInvoke   直到异步调用完成后才返回。这种技术非常适合文件或网络操作,但是由于它阻塞   EndInvoke,所以不要从用户界面的服务线程中使用它。

    [C#]
    public   class   AsyncMain   {
            static   void   Main(string[]   args)   {
                    //   The   asynchronous   method   puts   the   thread   id   here.
                    int   threadId;

                    //   Create   an   instance   of   the   test   class.
                    AsyncDemo   ad   =   new   AsyncDemo();

                    //   Create   the   delegate.
                    AsyncDelegate   dlgt   =   new   AsyncDelegate(ad.TestMethod);
         
                    //   Initiate   the   asychronous   call.
                    IAsyncResult   ar   =   dlgt.BeginInvoke(3000,  
                            out   threadId,   null,   null);

                    Thread.Sleep(0);
                    Console.WriteLine( "Main   thread   {0}   does   some   work. ",
                            AppDomain.GetCurrentThreadId());

                    //   Wait   for   the   WaitHandle   to   become   signaled.
                    ar.AsyncWaitHandle.WaitOne();

                    //   Perform   additional   processing   here.
                    //   Call   EndInvoke   to   retrieve   the   results.
                    string   ret   =   dlgt.EndInvoke(out   threadId,   ar);

                    Console.WriteLine( "The   call   executed   on   thread   {0},   with   return   value   \ "{1}\ ". ",   threadId,   ret);
            }
    }

    轮询异步调用完成
    您可以使用由   BeginInvoke   返回的   IAsyncResult   的   IsCompleted   属性来发现异步调用何时完成。从用户界面的服务线程中进行异步调用时可以执行此操作。轮询完成允许用户界面线程继续处理用户输入。


    [C#]
    public   class   AsyncMain   {
            static   void   Main(string[]   args)   {
                    //   The   asynchronous   method   puts   the   thread   id   here.
                    int   threadId;

                    //   Create   an   instance   of   the   test   class.
                    AsyncDemo   ad   =   new   AsyncDemo();

                    //   Create   the   delegate.
                    AsyncDelegate   dlgt   =   new   AsyncDelegate(ad.TestMethod);
         
                    //   Initiate   the   asychronous   call.
                    IAsyncResult   ar   =   dlgt.BeginInvoke(3000,  
                            out   threadId,   null,   null);

                    //   Poll   while   simulating   work.
                    while(ar.IsCompleted   ==   false)   {
                            Thread.Sleep(10);
                    }

                    //   Call   EndInvoke   to   retrieve   the   results.
                    string   ret   =   dlgt.EndInvoke(out   threadId,   ar);

                    Console.WriteLine( "The   call   executed   on   thread   {0},   with   return   value   \ "{1}\ ". ",   threadId,   ret);
            }
    }

    异步调用完成时执行回调方法
    如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法。回调方法在   ThreadPool   线程上执行。

    要使用回调方法,必须将代表该方法的   AsyncCallback   委托传递给   BeginInvoke。也可以传递包含回调方法将要使用的信息的对象。例如,可以传递启动调用时曾使用的委托,以便回调方法能够调用   EndInvoke。

    [C#]
    public   class   AsyncMain   {
            //   Asynchronous   method   puts   the   thread   id   here.
            private   static   int   threadId;

            static   void   Main(string[]   args)   {
                    //   Create   an   instance   of   the   test   class.
                    AsyncDemo   ad   =   new   AsyncDemo();

                    //   Create   the   delegate.
                    AsyncDelegate   dlgt   =   new   AsyncDelegate(ad.TestMethod);
         
                    //   Initiate   the   asychronous   call.     Include   an   AsyncCallback
                    //   delegate   representing   the   callback   method,   and   the   data
                    //   needed   to   call   EndInvoke.
                    IAsyncResult   ar   =   dlgt.BeginInvoke(3000,
                            out   threadId,  
                            new   AsyncCallback(CallbackMethod),
                            dlgt   );

                    Console.WriteLine( "Press   Enter   to   close   application. ");
                    Console.ReadLine();
            }
           
            //   Callback   method   must   have   the   same   signature   as   the
            //   AsyncCallback   delegate.
            static   void   CallbackMethod(IAsyncResult   ar)   {
                    //   Retrieve   the   delegate.
                    AsyncDelegate   dlgt   =   (AsyncDelegate)   ar.AsyncState;

                    //   Call   EndInvoke   to   retrieve   the   results.
                    string   ret   =   dlgt.EndInvoke(out   threadId,   ar);

                    Console.WriteLine( "The   call   executed   on   thread   {0},   with   return   value   \ "{1}\ ". ",   threadId,   ret);
            }
    }
  • 相关阅读:
    Android 自定义seekbar中,thumb被覆盖掉一部分问题
    Android SeekBar实现音量调节
    Android 设置thumb图片大小
    Android 图片处理方法
    Android 三档自定义滑动开关,禁止点击功能的实现,用默认的seekbar组件实现
    Android SeekBar自定义使用图片和颜色显示
    Android 使控件各占屏幕的一半
    Android ExpandableListView使用+获取SIM卡状态信息
    Android的5样的调试信息
    Js创建对象的做法
  • 原文地址:https://www.cnblogs.com/leon916/p/1757604.html
Copyright © 2011-2022 走看看