程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 什麼是.Net的異步機制(委托Delegate) - step 1

什麼是.Net的異步機制(委托Delegate) - step 1

編輯:關於.NET

在閱讀下面知識前,我已經認為你已經具有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 類的消息隊列。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved