在閱讀下面知識前,我已經認為你已經具有c#的基礎,包括簡單的委托知識; 代碼使用VS2008開發,但是會在.Net Framework 2.0(C Sharp)編寫
什麼是.Net異步機制呢?
在解釋這個話題前,我們先看看同步的程序,就是我們常用的Hello World 程序.
Code 1:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 // 查看當前的線程ID, 是否線程池裡面的線程
6 Console.WriteLine("1,Thread ID:#{0},Is PoolThread?{1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
7
8 AsyncTest test = new AsyncTest();
9 string val = test.Hello("Andy Huang");
10
11 Console.WriteLine(val);
12 Console.ReadLine(); // 讓黑屏等待,不會直接關閉..
13 }
14 }
15
16 public class AsyncTest
17 {
18 public string Hello(string name)
19 {
20 // 查看當前的線程ID, 是否線程池裡面的線程
21 Console.WriteLine("2,Thread ID:#{0},Is PoolThread?{1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
22 return "Hello:" + name;
23 }
24 }

圖1
我們可以從圖1看出,我們平常寫的Hello 程序是同一個線程的,而且不是線程池理的線程程序.
按照上面的程序稍做改動, 那麼開始我們第一個異步的Hello World 程序.
使用.Net 的委托機制來為我們的程序提供異步操作行為.
1步, 為我們的AsyncTest(Hello方法) 聲明一個委托
public delegate string AsyncEventHandler(string name);
2步,使用委托提供的BeginInvoke, EndInvoke 方法(具體使用下一篇文章詳細介紹)來提供異步的調用.
string val = test.Hello("Andy Huang");
修改為
AsyncEventHandler async = test.Hello;
IAsyncResult result = async.BeginInvoke("Andy Huang", null, null);
string val = async.EndInvoke(result);
下面是完整的代碼.
Code 2:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 // 查看當前的線程ID, 是否線程池裡面的線程
6 Console.WriteLine("1,Thread ID:#{0},Is PoolThread?{1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
7
8 AsyncTest test = new AsyncTest();
9 //把Hello 方法分配給委托對象
10 AsyncEventHandler async = test.Hello; //注釋1,建議用=,不用+=
11
12 //發起一個異步調用的方法,賦值"Andy Huang", 返回IAsyncResult 對象
13 IAsyncResult result = async.BeginInvoke("Andy Huang", null, null);
14
15 //這裡會阻礙線程,直到方法執行完畢
16 string val = async.EndInvoke(result);
17
18 Console.WriteLine(val);
19 Console.ReadLine(); // 讓黑屏等待,不會直接關閉..
20 }
21 }
22
23 //我們使用委托來提供.Net的異步機制
24 public delegate string AsyncEventHandler(string name);
25 public class AsyncTest
26 {
27 public string Hello(string name)
28 {
29 // 查看當前的線程ID, 是否線程池裡面的線程
30 Console.WriteLine("2,Thread ID:#{0},Is PoolThread?{1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
31 return "Hello:" + name;
32 }
33 }
注釋1: 用=操作符在於分配委托對象時候不需要初始化;並且異步調用時候只能有一個目標方法.

圖2
對比圖1 和圖2, ,可以看出(2,Thread ID:#10,Is PoolThread?True),在使用異步機制的時候,其實就是開啟一個新的線程來執行我們的方法,並且這個線程來自 線程堆. 到這裡,我們就很好的解釋了”什麼是.Net異步機制?”
說到這裡,結束了嗎? 可能大家會想其實使用異步就是多了個委托( public delegate string AsyncEventHandler(string name);) 那麼到底為我們做了些什麼呢?
通過反編譯(微軟提供的IL Disassembler)我們看到

圖3
編譯器為我們生成了下面類定義(其實委托就是一個類)
Code 3
public sealed class AsyncEventHandler : MulticastDelegate
{
public AsyncEventHandler(object @object, IntPtr method)
{....}
public virtual IAsyncResult BeginInvoke(string name, AsyncCallback callback, object @object)
{...}
public virtual string EndInvoke(IAsyncResult result)
{...}
public virtual string Invoke(string name)
{...}
}
繼承於MulticastDelegate, 提供了BeginInvoke / EndInvoke / Invoke.
Invoke 是我們Code 1 同步調用的方法,當然我們也可以直接使用Invoke來同步調用.
BeginInvoke / EndInvoke 是Code 2中使用的異步調用的方法,下篇文章我會詳細介紹
什麼時候使用.Net異步機制呢?
異步操作通常用於執行完成時間可能較長的任務,如打開大文件、連接遠程計算機或查詢數據庫。異步操作在主應用程序線程以外的線程中執行。應用程序調用方法異步執行某個操作時,應用程序仍然可以繼續執行當前的程序。
.NET Framework 的許多方面都支持異步編程功能,這些方面包括:
·文件(File) IO、流(Stream) IO、套接字(Socket) IO。
·網絡。
·遠程處理信道(HTTP、TCP)和代理。
·使用 ASP.NET 創建的 XML Web services。
·ASP.NET Web 窗體。
·使用 MessageQueue 類的消息隊列。
本文配套源碼