[转]关于c#的BeginInvoke/EndInvoke/回执调用

时间:2022-08-27 18:41:51
  1  using  System;
  2  using  System.Threading ;
  3 
  4  namespace  AsyncDemo
  5  {
  6       /**//**//**/ ///   <summary>
  7       ///  如何异步调用 Visual C# 方法
  8       ///  出自: http://support.microsoft.com/default.aspx?scid=kb%3Bzh-cn%3B315582
  9       ///   </summary>
 10       class  AsyncDemo
 11      {
 12           /**//**//**/ ///   <summary>
 13           ///  应用程序的主入口点。
 14           ///   </summary>
 15           [STAThread]
 16           static   void  Main( string [] args)
 17          {
 18              AsyncDemo ad  =   new  AsyncDemo () ;
 19               // ad.DemoSyncCall() ;
 20               // ad.DemoEndInvoke();
 21               // ad.DemoWaitHandle();
 22               // ad.DemoPolling();
 23              ad.DemoCallback();
 24              Console.WriteLine( " 1111111111 " );
 25              Console.Read();
 26          }
 27 
 28           string  LongRunningMethod ( int  iCallTime,  out   int  iExecThread)
 29          {
 30              Thread.Sleep (iCallTime) ;
 31              iExecThread  =  AppDomain.GetCurrentThreadId ();
 32               return   " MyCallTime was  "   +  iCallTime.ToString() ;
 33          }
 34 
 35           delegate   string  MethodDelegate( int  iCallTime,  out   int  iExecThread)  ;
 36 
 37           /**//**//**//*
 38           *  同步调用方法
 39           *  */
 40           /**//**//**/ ///   <summary>
 41           ///  示例 1: 同步调用方法
 42           ///   </summary>
 43           public   void  DemoSyncCall()
 44          {
 45               string  s ;
 46               int  iExecThread;
 47 
 48                //  Create an instance of a delegate that wraps LongRunningMethod.
 49              MethodDelegate dlgt  =   new  MethodDelegate ( this .LongRunningMethod) ;  
 50              
 51               //  Call LongRunningMethod using the delegate.
 52               s  =  dlgt( 3000 out  iExecThread);  
 53              
 54              Console.WriteLine( string .Format ( " The delegate call returned the string:   [转]关于c#的BeginInvoke/EndInvoke/回执调用{0}, and the thread ID {1} " , s, iExecThread.ToString() ) );
 55                                       
 56           }
 57 
 58           /**//**//**//*
 59           * 使用调用模式是要调用 BeginInvoke , 做某些处理主线程, 并调用 EndInvoke() 。 
 60           * 注意不 EndInvoke() 不返回直到异步调用已完成。 
 61           * 此调用模式是有用当要有调用线程正在执行异步调用, 同时工作。 
 62           * 有同时发生工作可改善许多应用程序的性能。 
 63           * 常见任务以异步运行以此方式是文件或网络操作。 
 64           *  */
 65           /**//**//**/ ///   <summary>
 66           ///  示例 2: 通过 EndInvoke() 调用模式异步调用方法        
 67           ///   </summary>
 68           public   void  DemoEndInvoke()
 69          {
 70              MethodDelegate dlgt  =   new  MethodDelegate ( this .LongRunningMethod) ;
 71               string  s ;
 72               int  iExecThread;
 73 
 74               //  Initiate the asynchronous call.
 75              IAsyncResult ar  =  dlgt.BeginInvoke( 3000 out  iExecThread,  null null );  
 76 
 77               //  Do some useful work here. This would be work you want to have
 78               //  run at the same time as the asynchronous call.
 79 
 80               //  Retrieve the results of the asynchronous call.
 81              s  =  dlgt.EndInvoke ( out  iExecThread, ar) ;  
 82 
 83              Console.WriteLine( string .Format ( " The delegate call returned the string:   [转]关于c#的BeginInvoke/EndInvoke/回执调用{0}, and the number {1} " , s, iExecThread.ToString() ) );
 84          }
 85 
 86           /**//**//**//*
 87           * 由 BeginInvoke() 返回 IAsyncResult 具有一个 AsyncWaitHandle 属性。 
 88           * 该属性返回 WaitHandle 异步调用完成后, 通知是。 等待 WaitHandle 是常见线程同步技术。 
 89           * 通过是 WaitHandle WaitOne() 方法调用线程等待 WaitHandle 上。 
 90           * 直到是通知 WaitHandle WaitOne() 块。 当 WaitOne() 返回, 您在调用 EndInvoke() 之前进行一些额外工作。 
 91           * 对于执行文件或网络操作, 否则会阻塞调用主线程存为, 以前示例中此技术很有用。
 92           *  */
 93           /**//**//**/ ///   <summary>
 94           ///  示例 3: 异步调用方法并使用 A WaitHandle 来等待调用完成
 95           ///   </summary>
 96           public   void  DemoWaitHandle ()
 97           {
 98               string  s ;
 99               int  iExecThread;
100 
101              MethodDelegate dlgt  =   new  MethodDelegate ( this .LongRunningMethod) ;
102  
103               //  Initiate the asynchronous call.
104              IAsyncResult ar  =  dlgt.BeginInvoke( 3000 out  iExecThread,  null null ); 
105 
106               //  Do some useful work here. This would be work you want to have
107               //  run at the same time as the asynchronous call.
108 
109               //  Wait for the WaitHandle to become signaled.
110              ar.AsyncWaitHandle.WaitOne() ;
111 
112                //  Get the results of the asynchronous call.
113              s  =  dlgt.EndInvoke ( out  iExecThread, ar) ;
114              
115              Console.WriteLine( string .Format ( " The delegate call returned the string:   [转]关于c#的BeginInvoke/EndInvoke/回执调用{0}, and the number {1} " , s, iExecThread.ToString() ) );
116          }        
117 
118           /**//**//**//*
119           * 由 BeginInvoke() 返回 IAsyncResult 对象有个 IsCompleted 属性异步调用完成后返回 True 。 
120           * 然后可调用 EndInvoke() 。 如果您应用程序不断工作对不做要长期函数调用已被此调用模式很有用。 
121           * MicrosoftWindows 应用程序是这样的示例。 
122           * 主线程的 Windows 应用程序可以继续以执行异步调用时处理用户输入。 
123           * 它可定期检查 IsCompleted 到调用是否完成。 它调用 EndInvoke 当 IsCompleted 返回 True 。 
124           * 直到它知道操作已完成因为 EndInvoke() 阻止直到异步操作为完整, 应用程序不调用它。 
125           *  */
126           /**//**//**/ ///   <summary>
127           ///  示例 4: 异步调用方法通过轮询调用模式
128           ///   </summary>
129           public   void  DemoPolling()
130          {
131              MethodDelegate dlgt  =   new  MethodDelegate ( this .LongRunningMethod) ;
132               string  s ;
133               int  iExecThread;
134 
135               //  Initiate the asynchronous call.
136              IAsyncResult ar  =  dlgt.BeginInvoke( 3000 out  iExecThread,  null null ); 
137 
138               //  Poll IAsyncResult.IsCompleted
139               while (ar.IsCompleted  ==   false )
140               {
141                  Thread.Sleep ( 10 ) ;   //  pretend to so some useful work
142              }
143              s  =  dlgt.EndInvoke ( out  iExecThread, ar) ;
144 
145              Console.WriteLine( string .Format ( " The delegate call returned the string:   [转]关于c#的BeginInvoke/EndInvoke/回执调用{0}, and the number {1} " , s, iExecThread.ToString() ) );
146          }
147 
148           /**//**//**//*
149           * 本节, 中示例提供对 BeginInvoke() 函数, 异步调用完成后系统执行回调委托。 
150           * 回调调用 EndInvoke() 并处理异步调用的结果。 
151           * 如果启动异步调用线程不需要处理结果是调用此调用模式很有用。 
152           * 异步调用完成后系统调用线程以外启动线程上调。 
153           * 若使用此调用模式, 作为第二到最后 - BeginInvoke() 函数的参数必须传递 AsyncCallback 类型的委托。 
154           * BeginInvoke() 还有最后参数键入 对象 到您可以将任何对象。 当它调用该对象可用于您回调函数。 
155           * 为此参数一个重要用途是以传递用于初始化调用该委托。 
156           * 回调函数然后使用与该委托 EndInvoke() 函数来完成调用。 此调用模式是所示。
157           *  */
158           /**//**//**/ ///   <summary>
159           ///  示例 5: 异步方法完成后执行回调
160           ///   </summary>
161           public   void  DemoCallback()
162          {
163               MethodDelegate dlgt  =   new  MethodDelegate ( this .LongRunningMethod) ;
164               // string s ;
165               int  iExecThread;
166 
167               //  Create the callback delegate.
168              AsyncCallback cb  =   new  AsyncCallback(MyAsyncCallback);
169 
170               //  Initiate the Asynchronous call passing in the callback delegate
171               //  and the delegate object used to initiate the call.
172              IAsyncResult ar  =  dlgt.BeginInvoke( 3000 out  iExecThread, cb,dlgt); 
173          }
174 
175           public   void  MyAsyncCallback(IAsyncResult ar)
176          {
177               string  s ;
178               int  iExecThread ;
179 
180               //  Because you passed your original delegate in the asyncState parameter
181               //  of the Begin call, you can get it back here to complete the call.
182               MethodDelegate dlgt  =  (MethodDelegate) ar.AsyncState;
183 
184               //  Complete the call.
185              s  =  dlgt.EndInvoke ( out  iExecThread, ar) ;
186 
187              Console.WriteLine( string .Format ( " The delegate call returned the string:   [转]关于c#的BeginInvoke/EndInvoke/回执调用{0}, and the number {1} " , s, iExecThread.ToString() ));
188          }    
189      }
190  }