.NET組件程式設計——非同步呼叫

來源:互聯網
上載者:User

引言

在進行一個對象的方法調用時,對象執行調用期間用戶端通常是被阻塞的,且只有該方法執行完畢並且返回時,控制權才會回到用戶端。當提及這樣的需求,作為開發人員的你會使用何種方式完成呢?通常情況下我們都會使用多線程來滿足這種需求。然而對於個人而言,實現一個強健的非同步呼叫執行是不堪重負的,需要嘔心瀝血的設計、實現、測試。不過,在使用.Net開發時,我們可以使用非同步呼叫方式來滿足客戶需求。

 

什麼是非同步呼叫

.Net設計師考慮到了這個問題,為了讓你集中精力在手頭的業務問題的解決,而非繁雜的非同步呼叫問題,提出了非同步呼叫。有的時候你需要把調用的方法A放在後台執行,此時控制權可以立即返回用戶端,執行完方法A後以某種方式通知用戶端A方法已經執行完畢,這種執行模式被稱為非同步方法呼叫調。實現這種操作就需要使用非同步呼叫。在學習非同步呼叫之前,首先我們要瞭解委託的內部原理。

 

使用非同步呼叫離不開委託

我們建立一個Windows Form應用程式。

項目中添加一個計算類Calculator,包含加、減法運算 

public class Calculator{    public int Add(int arg1, int arg2)    {        return arg1 + arg2;    }    public int Subtract(int arg1, int arg2)    {        return arg1 - arg2;    }}

 在Form1中添加一個按鈕

 

在Form1類中添加一個委託

public delegate int BinaryOperation(int arg1, int arg2);

 雙擊按鈕添加Click事件

private void button1_Click(object sender, EventArgs e){    Calculator c = new Calculator();    // 也可以使用+=,後面有解釋,與這裡知識無關     BinaryOperation oppDel = c.Add;    int result = 0;    result = oppDel(2, 3);    MessageBox.Show("result = " + result);}

 運行後顯示結果:result=5


委託的原理

運行到此,聰明的人會在思考一個問題,這種委託方式內部是如何?的。

編譯器發現BinaryOperation委託,他會將BinaryOperation委託代碼編譯為

public sealed class BinaryOperation : MulticastDelegate{public BinaryOperation(object target, int methodPtr){}public virtual int Invoke(int arg1, int arg2){}public virtual IAsyncResult Begin(int arg1, int arg2, AsyncCallback callback, object asyncState){}public virtual int EndInvoke(IAsyncResult result){}}

當我們調用委託oppDel(2, 3)時,編譯器會轉變對Invoke(int arg1, int arg2)的調用。Invoke方法會阻塞調用者,在調用者線程上執行這個方法,然後把控制權交給調用者。

BinaryOperation oppDel = c.Add;int result = 0;result = oppDel(2, 3);

BinaryOperation類是從MulticastDelegate類派生而來的,MulticastDelegate提供了每個委託都有的內部委託列表實現,而這些委託均派生自抽象類別Delegate(本部落格事件章節有詳細介紹)。編譯器也聲明了兩個方法來管理非同步方法呼叫調用。BeginInvoke()和EndInvoke(),而他們的正確使用是本章節的主題。

 

非同步呼叫的編程模型
要支援非同步呼叫,多線程是必不可少的。如果.Net為每個非同步呼叫方法都建立一個新線程,無疑是一個巨大的資源浪費,同時也會導致效能的損失。一個比較好的方法是使用已經建立的背景工作執行緒池。.Net中正有這樣的線程池,被稱為.Net線程池。在.Net中隱蔽了非同步呼叫的互動。這裡我們主要闡述阻塞、等待、輪循、完成回調。

總的思路是:BeginInvoke()發起一個非同步方法呼叫調用,在將請求放入隊列時,會短暫的阻塞用戶端,然後控制權又回到用戶端。EndInvoke()管理方法的完成,包括輸出參數和傳回值,以及錯誤處理。

 

使用BeginInvoke()和EndInvoke()

 編譯器產生的BeginInvoke()和EndInvoke()有如下格式:

public virtual IAsyncResult BeginInvoke(<input and input/output parameters>, AsyncCallback callback, object asyncState);public virtual <return value> EndInvoke(<outpub and input/output parameters>, IAsyncResult asyncResult);

BeginInvoke接受兩個額外參數:AsyncCallback回調和asyncState對象,這兩個不在原始委託簽名中。回調參數實際上是一個委派物件,代表對一個回調方法的引用,該方法用於接收方法完成事件的通知。asyncState是一個通用對象,該對象傳遞任何狀態資訊,這些資訊是處理方法完成的一方所必須的。這兩個參數是可選的,可以傳遞兩個null或選擇其一。

Calculator c = new Calculator();BinaryOperation oppDel = c.Add;oppDel.BeginInvoke(2, 3, null, null);

通過這樣的方式,任意一個類都支援同步或非同步呼叫。

 

如何獲得非同步方法呼叫調用結果

從上面的代碼不難看出BeginInvoke方法返回一個實現了IAsyncResult介面對象,IAsyncResult定義如下:

public interface IAsyncResult{    object AsyncState{get;}    WaitHandle AsyncWaitHandle{get;}    bool CompletedSynchronously{get;}    bool IsCompleted{get;}}

我們可以看到,在.Net中使用IAsynResult對象唯一標示BeginInvoke方法的傳回值,你可以把IAsyncResult對象傳遞給EndInvoke(),以此標識需要取得那個非同步方法呼叫的執行結果。

介面添加一個《非同步計算1》按鈕,

Click事件

private void button2_Click(object sender, EventArgs e){    Calculator c = new Calculator();    BinaryOperation oppDel = c.Add;    IAsyncResult asyncResult1 = oppDel.BeginInvoke(2, 3, null, null);    IAsyncResult asyncResult2 = oppDel.BeginInvoke(5, 5, null, null);    // 注意輸出順序     MessageBox.Show(oppDel.EndInvoke(asyncResult2).ToString());    MessageBox.Show(oppDel.EndInvoke(asyncResult1).ToString());}

輸出結果10,5
上面案例展示幾個關鍵點:

1、EndInvoke主要用途是擷取輸出參數的和方法的傳回值,EndInvoke阻塞了調用者直到他等待的方法傳回值。

2、同一個委派物件會有多個非同步呼叫,如oppDel委派物件,我們進行了兩次BeginInvoke。我們通過傳入EndInvoke的IAsyncResult對象標識對應關係。

3、非同步呼叫順序是不可測的,所以不要對次序做任何假設。

 

 

 

 

 

非同步呼叫的優點

非同步呼叫可以提高應用程式的可用性

提高其輸送量和效能

提供更好的向外擴充能力

 

 

 

 

 

 

 

 

持續更新中...

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.