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

  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(3000out iExecThread);  
 53             
 54             Console.WriteLine(string.Format ("The delegate call returned the string:   {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(3000out iExecThread, nullnull);  
 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:   {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(3000out iExecThread, nullnull); 
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:   {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(3000out iExecThread, nullnull); 
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:   {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(3000out 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:   {0}, and the number {1}", s, iExecThread.ToString() ));
188         }    
189     }
190 }
posted @ 2009-03-14 16:47  波波的笔记  阅读(1055)  评论(0编辑  收藏  举报