C#多線程編程之:非同步方法呼叫調用

來源:互聯網
上載者:User

非同步方法呼叫

  當一個線程調用方法後,直到方法執行完畢,線程才繼續執行,這種方法被稱為同步方法。然而,有些方法執行時間可能非常長,比如串口操作或訪問網路,這樣線程被阻塞,而無法響應使用者的其他請求。這種情況通常是無法忍受的,所以這時我們應該使用非同步方法呼叫。

  非同步方法呼叫的原理是,在方法調用前為非同步方法呼叫指定一個回呼函數,方法調用後被線程池中的一個線程接管,執行該方法。主線程立即返回,繼續執行其他工作或響應使用者請求。如果非同步方法呼叫執行完畢,回呼函數被自動執行,以處理非同步方法呼叫的調用結果。

  如何?非同步方法呼叫呢?C#通過非同步委託調用BeginInvoke和EndInvoke方法來實現非同步方法呼叫。

BeginInvoke方法原型:

  IAsyncResult BeginInvoke(......, AsyncCallback callback, object o);
  ......表示非同步委託中定義的參數列表。
  AsyncCallback參數是一個用於回呼函數的委託,它的原型為:
  public delegate void AsyncCallback(IAsyncResult ar)。其中IAsyncResult參數用於封裝非同步方法呼叫的執行結果。
  Object參數用於在主線程與回呼函數間傳遞一些附加資訊,如同步資訊。

EndInvoke方法原型:

  xxx EndInvoke(IAsyncResult result);
  xxx表示非同步委託原型中定義的返回資料類型,IAsyncResult用於封裝非同步方法呼叫的執行結果。

  這麼看著是不是有點迷糊?看個例子就明白了:

using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace ProcessTest
{
class Program
{
//非同步呼叫執行完成同步訊號
static AutoResetEvent ev = new AutoResetEvent(false);
//定義委託
public delegate int Deleg(int a, int b);

static int WriteSum(int a, int b)
{
//顯示當前線程ID號及Sum值
Console.WriteLine("執行WriteSum的線程ID為:{0},Sum = {1}", Thread.CurrentThread.ManagedThreadId, a + b);
return a + b;
}

//回呼函數
static void SumDone(IAsyncResult async)
{
//等待1秒,類比線程正在執行其他工作
Thread.Sleep(1000);

//async中封裝了非同步方法呼叫執行的結果
//從操作結果async中還原委託
Deleg proc = ((AsyncResult)async).AsyncDelegate as Deleg;
//擷取非同步方法呼叫的執行結果
int sum = proc.EndInvoke(async);

//顯示結果
Console.WriteLine("執行SumDone的線程ID為:{0},Sum = {1}", Thread.CurrentThread.ManagedThreadId, sum);

//使用AsnycState屬性擷取主線程中傳入的同步訊號
//釋放同步訊號表示非同步呼叫已完成
((AutoResetEvent)async.AsyncState).Set();


}

static void Main(string[] args)
{
//建立一個委託
Deleg proc = new Deleg(WriteSum);

//採用非同步方式調用委託
//指定SumDone為非同步作業完成後的回呼函數
//指定ev為object參數,用於同步回呼函數與主線程間操作
IAsyncResult async = proc.BeginInvoke(10, 10, SumDone, ev);
Console.WriteLine("主線程ID號為:{0},非同步作業已開始執行,正等待操作完成。", Thread.CurrentThread.ManagedThreadId);

//等待非同步作業完成
ev.WaitOne();
Console.WriteLine("非同步作業已完成!");

System.Console.ReadKey();
}
}
}

 

  是程式的運行結果:

  

  注意觀察運行結果,非同步方法呼叫和回呼函數是在同一步線程執行。

為方法指定OneWay特性

  我們可將System.Runtime.Remoting.Messaging.OneWay特性應用於任何一個方法,該特性告訴CLR該方法不返回任何資訊。即使該方法實際返回了資料(通過return語句或out、ref定義的參數),但只要被標記了OneWay特性,那它就不會再返回任何資訊。

  一個被標記為OneWay特性的方法即可以同步方式調用,也可以非同步方式調用。如果在它的執行過程中引起了一個異常卻沒有捕獲,在同步方式下,該異常會向上傳播;但在非同步方式下,該異常將不會被傳播。大多數情況下,被標記為OneWay的方法是以非同步方式工作。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.