异步调用之我见

今天总算把.NET SDK中的关于异步调用的部分看完了,看完之后没觉得很复杂,可能是以前看一些别的书籍或材料把问题复杂化了吧,当然,还有可能是自己没有认识全面哈,有错误的地方大家指出来。
异步调用总共分为四类调用,其中两类block方式,两类非block方式:

1.Blocking Application Execution by Ending an Asynchronous Operation.
2.Blocking Application Execution Using an AsyncWaitHandle.

3.Polling for the Status of an Asynchronous Operation.
4.Using an AsyncCallback Delegate to End an Asynchronous Operation.

先说说两类block方式吧,
第一个就是通过调用对象的End.....方法阻塞当前线程,直到得到IAsyncResult为止,所谓异步呢就是在调用对象的Begin...方法和End...方法之间可以执行别的操作,而让另一个线程去做事。
第二个则更为灵活一些,它是通过调用IAsyncResult中的Wait...方法实现当前线程的阻塞。所谓异步呢就是在调用Begin...方法和Wait...方法之间可以执行别的操作,而让另一个线程干别的事.

在说说两个非block方式:
第三个是通过轮询的方式,就是在执行玩Begin...方法之后,得到IAsyncResult,我过一段时间就去问问(查看IAsyncResult.IsCompleted是否为真),完了我就继续执行,没完我就可以边做边等,这就是所谓的异步。
最后一个也是最最灵活的一个,就是通过回调,说白了就是调用Begin...方法完后,我去干别的,你去处理这件事,我给你一个方法名字,你干完了就执行这个函数就行了,只不过呢这个函数有点特殊,他是异步回调函数,就是要声明成AsyncCallback类型才行

下面给出了四种异步调用的例子(From SDK)
1.Blocking Application Execution by Ending an Asynchronous Operation.
 1 /*
 2 The following example demonstrates using asynchronous methods to
 3 get Domain Name System information for the specified host computer.
 4 */
 5 
 6 using System;
 7 using System.Net;
 8 using System.Net.Sockets;
 9 
10 namespace Examples.AdvancedProgramming.AsynchronousOperations
11 {
12     public class BlockUntilOperationCompletes
13     {
14         public static void Main(string[] args)
15         {
16             // Make sure the caller supplied a host name.
17             if (args.Length == 0 || args[0].Length == 0)
18             {
19                 // Print a message and exit.
20                 Console.WriteLine("You must specify the name of a host computer.");
21                 return;
22             }
23             // Start the asynchronous request for DNS information.
24             // This example does not use a delegate or user-supplied object
25             // so the last two arguments are null.
26             IAsyncResult result = Dns.BeginGetHostEntry(args[0], nullnull);
27             Console.WriteLine("Processing your request for information");
28             // Do any additional work that can be done here.
29             try 
30             {
31                 // EndGetHostByName blocks until the process completes.
32                 IPHostEntry host = Dns.EndGetHostEntry(result);
33                 string[] aliases = host.Aliases;
34                 IPAddress[] addresses = host.AddressList;
35                 if (aliases.Length > 0)
36                 {
37                     Console.WriteLine("Aliases");
38                     for (int i = 0; i < aliases.Length; i++)
39                     {
40                         Console.WriteLine("{0}", aliases[i]);
41                     }
42                 }
43                 if (addresses.Length > 0)
44                 {
45                     Console.WriteLine("Addresses");
46                     for (int i = 0; i < addresses.Length; i++)
47                     {
48                         Console.WriteLine("{0}",addresses[i].ToString());
49                     }
50                 }
51             }
52             catch (SocketException e)
53             {
54                 Console.WriteLine("An exception occurred while processing the request: {0}", e.Message);
55             }
56         }
57     }
58 }
59 
60 
2. Blocking Application Execution Using an AsyncWaitHandle.
 1 /*
 2 The following example demonstrates using asynchronous methods to
 3 get Domain Name System information for the specified host computer.
 4 
 5 */
 6 
 7 using System;
 8 using System.Net;
 9 using System.Net.Sockets;
10 using System.Threading;
11 
12 namespace Examples.AdvancedProgramming.AsynchronousOperations
13 {
14     public class WaitUntilOperationCompletes
15     {
16         public static void Main(string[] args)
17         {
18             // Make sure the caller supplied a host name.
19             if (args.Length == 0 || args[0].Length == 0)
20             {
21                 // Print a message and exit.
22                 Console.WriteLine("You must specify the name of a host computer.");
23                 return;
24             }
25             // Start the asynchronous request for DNS information.
26             IAsyncResult result = Dns.BeginGetHostEntry(args[0], nullnull);
27             Console.WriteLine("Processing request for information");
28             // Wait until the operation completes.
29             result.AsyncWaitHandle.WaitOne();
30             // The operation completed. Process the results.
31             try 
32             {
33                 // Get the results.
34                 IPHostEntry host = Dns.EndGetHostEntry(result);
35                 string[] aliases = host.Aliases;
36                 IPAddress[] addresses = host.AddressList;
37                 if (aliases.Length > 0)
38                 {
39                     Console.WriteLine("Aliases");
40                     for (int i = 0; i < aliases.Length; i++)
41                     {
42                         Console.WriteLine("{0}", aliases[i]);
43                     }
44                 }
45                 if (addresses.Length > 0)
46                 {
47                     Console.WriteLine("Addresses");
48                     for (int i = 0; i < addresses.Length; i++)
49                     {
50                         Console.WriteLine("{0}",addresses[i].ToString());
51                     }
52                 }
53             }
54             catch (SocketException e)
55             {
56                 Console.WriteLine("Exception occurred while processing the request: {0}"
57                     e.Message);
58             }
59         }
60     }
61 }
62 
63 
3. Polling for the Status of an Asynchronous Operation.
 1 /*
 2 The following example demonstrates using asynchronous methods to
 3 get Domain Name System information for the specified host computer.
 4 This example polls to detect the end of the asynchronous operation.
 5 */
 6 
 7 using System;
 8 using System.Net;
 9 using System.Net.Sockets;
10 using System.Threading;
11 
12 namespace Examples.AdvancedProgramming.AsynchronousOperations
13 {
14     public class PollUntilOperationCompletes
15     {
16         static void UpdateUserInterface()
17         {
18             // Print a period to indicate that the application
19             // is still working on the request.
20             Console.Write(".");
21         }
22         public static void Main(string[] args)
23         {
24             // Make sure the caller supplied a host name.
25             if (args.Length == 0 || args[0].Length == 0)
26             {
27                 // Print a message and exit.
28                 Console.WriteLine("You must specify the name of a host computer.");
29                 return;
30             }
31             // Start the asychronous request for DNS information.
32             IAsyncResult result = Dns.BeginGetHostEntry(args[0], nullnull);
33             Console.WriteLine("Processing request for information");
34             
35             // Poll for completion information.
36             // Print periods (".") until the operation completes.
37             while (result.IsCompleted != true)
38             {
39                 UpdateUserInterface();
40             }
41             // The operation is complete. Process the results.
42             // Print a new line.
43             Console.WriteLine();
44             try 
45             {
46                 IPHostEntry host = Dns.EndGetHostEntry(result);
47                 string[] aliases = host.Aliases;
48                 IPAddress[] addresses = host.AddressList;
49                 if (aliases.Length > 0)
50                 {
51                     Console.WriteLine("Aliases");
52                     for (int i = 0; i < aliases.Length; i++)
53                     {
54                         Console.WriteLine("{0}", aliases[i]);
55                     }
56                 }
57                 if (addresses.Length > 0)
58                 {
59                     Console.WriteLine("Addresses");
60                     for (int i = 0; i < addresses.Length; i++)
61                     {
62                         Console.WriteLine("{0}",addresses[i].ToString());
63                     }
64                 }
65             }
66             catch (SocketException e)
67             {
68                 Console.WriteLine("An exception occurred while processing the request: {0}", e.Message);
69             }
70         }
71     }
72 }
73 
74 
4.Using an AsyncCallback Delegate to End an Asynchronous Operation.
  1 /*
  2 The following example demonstrates using asynchronous methods to
  3 get Domain Name System information for the specified host computers.
  4 This example uses a delegate to obtain the results of each asynchronous 
  5 operation.
  6 */
  7 
  8 using System;
  9 using System.Net;
 10 using System.Net.Sockets;
 11 using System.Threading;
 12 using System.Collections.Specialized;
 13 using System.Collections;
 14 
 15 namespace Examples.AdvancedProgramming.AsynchronousOperations
 16 {
 17     public class UseDelegateForAsyncCallback
 18     {
 19         static int requestCounter;
 20         static ArrayList hostData = new ArrayList();
 21         static StringCollection hostNames = new StringCollection();
 22         static void UpdateUserInterface()
 23         {
 24             // Print a message to indicate that the application
 25             // is still working on the remaining requests.
 26             Console.WriteLine("{0} requests remaining.", requestCounter);
 27         }
 28         public static void Main()
 29         {
 30             // Create the delegate that will process the results of the 
 31             // asynchronous request.
 32             AsyncCallback callBack = new AsyncCallback(ProcessDnsInformation);
 33             string host;
 34             do
 35             {
 36                 Console.Write(" Enter the name of a host computer or <enter> to finish: ");
 37                 host = Console.ReadLine();
 38                 if (host.Length > 0)
 39                 {
 40                     // Increment the request counter in a thread safe manner.
 41                     Interlocked.Increment(ref requestCounter);
 42                     // Start the asynchronous request for DNS information.
 43                     Dns.BeginGetHostEntry(host, callBack, host);
 44                  }
 45             } while (host.Length > 0);
 46             // The user has entered all of the host names for lookup.
 47             // Now wait until the threads complete.
 48             while (requestCounter > 0)
 49             {
 50                 UpdateUserInterface();
 51             }
 52             // Display the results.
 53             for (int i = 0; i< hostNames.Count; i++)
 54             {
 55                 object data = hostData [i];
 56                 string message = data as string;
 57                 // A SocketException was thrown.
 58                 if (message != null)
 59                 {
 60                     Console.WriteLine("Request for {0} returned message: {1}"
 61                         hostNames[i], message);
 62                     continue;
 63                 }
 64                 // Get the results.
 65                 IPHostEntry h = (IPHostEntry) data;
 66                 string[] aliases = h.Aliases;
 67                 IPAddress[] addresses = h.AddressList;
 68                 if (aliases.Length > 0)
 69                 {
 70                     Console.WriteLine("Aliases for {0}", hostNames[i]);
 71                     for (int j = 0; j < aliases.Length; j++)
 72                     {
 73                         Console.WriteLine("{0}", aliases[j]);
 74                     }
 75                 }
 76                 if (addresses.Length > 0)
 77                 {
 78                     Console.WriteLine("Addresses for {0}", hostNames[i]);
 79                     for (int k = 0; k < addresses.Length; k++)
 80                     {
 81                         Console.WriteLine("{0}",addresses[k].ToString());
 82                     }
 83                 }
 84             }
 85        }
 86 
 87         // The following method is called when each asynchronous operation completes.
 88         static void ProcessDnsInformation(IAsyncResult result)
 89         {
 90             string hostName = (string) result.AsyncState;
 91             hostNames.Add(hostName);
 92             try 
 93             {
 94                 // Get the results.
 95                 IPHostEntry host = Dns.EndGetHostEntry(result);
 96                 hostData.Add(host);
 97             }
 98             // Store the exception message.
 99             catch (SocketException e)
100             {
101                 hostData.Add(e.Message);
102             }
103             finally 
104             {
105                 // Decrement the request counter in a thread-safe manner.
106                 Interlocked.Decrement(ref requestCounter);
107             }
108         }
109     }
110 }
111 
112 

posted @ 2007-01-28 17:49  29decibel  阅读(245)  评论(0)    收藏  举报