熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C#異步編程模式IAsyncResult概述

2013-11-13 09:53:10  來源: .NET編程 

  IAsyncResult 異步設計模式通過名為 BeginOperationName 和 EndOperationName 的兩個方法來實現原同步方法的異步調用如 FileStream 類提供了 BeginRead 和 EndRead 方法來從文件異步讀取字節它們是 Read 方法的異步版本

  Begin 方法包含同步方法簽名中的任何參數此外還包含另外兩個參數一個AsyncCallback 委托和一個用戶定義的狀態對象委托用來調用回調方法狀態對象是用來向回調方法傳遞狀態信息該方法返回一個實現 IAsyncResult 接口的對象

  End 方法用於結束異步操作並返回結果因此包含同步方法簽名中的 ref 和 out 參數返回值類型也與同步方法相同該方法還包括一個 IAsyncResult 參數用於獲取異步操作是否完成的信息當然在使用時就必須傳入對應的 Begin 方法返回的對象實例

  開始異步操作後如果要阻止應用程序可以直接調用 End 方法這會阻止應用程序直到異步操作完成後再繼續執行也可以使用 IAsyncResult 的 AsyncWaitHandle 屬性調用其中的WaitOne等方法來阻塞線程這兩種方法的區別不大只是前者必須一直等待而後者可以設置等待超時

  如果不阻止應用程序則可以通過輪循 IAsyncResult 的 IsCompleted 狀態來判斷操作是否完成或使用 AsyncCallback 委托來結束異步操作AsyncCallback 委托包含一個 IAsyncResult 的簽名回調方法內部再調用 End 方法來獲取操作執行結果

  代碼

  C#異步編程模式IAsyncResult之IAsyncResult 接口

  public interface IAsyncResult

  {

  object AsyncState { get; }

  WaitHandle AsyncWaitHandle { get; }

  bool CompletedSynchronously { get; }

  bool IsCompleted { get; }

  }

  我用一個 AsyncDemo 類作為異步方法的提供者後面的程序都會調用它內部很簡單構造函數接收一個字符串作為 name Run 方法輸出 My name is + name 而異步方法直接用委托的 BeginInvoke 和 EndInvoke 方法實現

  public class AsyncDemo

  {

  // Use in asynchronous methods

  private delegate string runDelegate();

  private string m_Name;

  private runDelegate m_Delegate;

  public AsyncDemo(string name)

  {

  m_Name = name;

  m_Delegate = new runDelegate(Run);

  }

  /**//// ﹤summary﹥

  /// Synchronous method

  /// ﹤/summary﹥

  /// ﹤returns﹥﹤/returns﹥

  public string Run()

  {

  return My name is + m_Name;

  }

  /**//// ﹤summary﹥

  /// Asynchronous begin method

  /// ﹤/summary﹥

  /// ﹤param name=callBack﹥﹤/param﹥

  /// ﹤param name=stateObject﹥﹤/param﹥

  /// ﹤returns﹥﹤/returns﹥

  public IAsyncResult BeginRun(

  AsyncCallback callBack Object stateObject)

  {

  try

  {

  return m_DelegateBeginInvoke(callBack stateObject);

  }

  catch(Exception e)

  {

  // Hide inside method invoking stack

  throw e;

  }

  }

  /**//// ﹤summary﹥

  /// Asynchronous end method

  /// ﹤/summary﹥

  /// ﹤param name=ar﹥﹤/param﹥

  /// ﹤returns﹥﹤/returns﹥

  public string EndRun(IAsyncResult ar)

  {

  if (ar == null)

  throw new NullReferenceException(

  Arggument ar cant be null);

  try

  {

  return m_DelegateEndInvoke(ar);

  }

  catch (Exception e)

  {

  // Hide inside method invoking stack

  throw e;

  }

  }

  }

  C#異步編程模式IAsyncResult操作步驟首先是 Begin 之後直接調用 End 方法當然中間也可以做其他的操作

  class AsyncTest

  {

  static void Main(string[] args)

  {

  AsyncDemo demo = new AsyncDemo(jiangnii);

  // Execute begin method

  IAsyncResult ar = demoBeginRun(null null);

  // You can do other things here

  // Use end method to block thread

  // until the operation is complete

  string demoName = demoEndRun(ar);

  ConsoleWriteLine(demoName);

  }

  }

  也可以用 IAsyncResult 的 AsyncWaitHandle 屬性我在這裡設置為秒超時

  class AsyncTest

  {

  static void Main(string[] args)

  {

  AsyncDemo demo = new AsyncDemo(jiangnii);

  // Execute begin method

  IAsyncResult ar = demoBeginRun(null null);

  // You can do other things here

  // Use AsyncWaitHandleWaitOne method to block thread for second at most

  arAsyncWaitHandleWaitOne( false);

  if (arIsCompleted)

  {

  // Still need use end method to get result

  // but this time it will return immediately

  string demoName = demoEndRun(ar);

  ConsoleWriteLine(demoName);

  }

  else

  {

  ConsoleWriteLine(Sorry

  cant get demoName the time is over);

  }

  }

  }

  C#異步編程模式IAsyncResult要注意的還有不中斷的循環每次循環輸出一個

  class AsyncTest

  {

  static void Main(string[] args)

  {

  AsyncDemo demo = new AsyncDemo(jiangnii);

  // Execute begin method

  IAsyncResult ar = demoBeginRun(null null);

  ConsoleWrite(Waiting);

  while (!arIsCompleted)

  {

  ConsoleWrite();

  // You can do other things here

  }

  ConsoleWriteLine();

  // Still need use end method to get result

  //but this time it will return immediately

  string demoName = demoEndRun(ar);

  ConsoleWriteLine(demoName);

  }

  }

  最後是使用回調方法並加上狀態對象狀態對象被作為 IAsyncResult 參數的 AsyncState 屬性被傳給回調方法回調方法執行前不能讓主線程退出我這裡只是簡單的讓其休眠了另一個與之前不同的地方是 AsyncDemo 對象被定義成了類的靜態字段以便回調方法使用

  class AsyncTest

  {

  static AsyncDemo demo = new AsyncDemo(jiangnii);

  static void Main(string[] args)

  {

  // State object

  bool state = false;

  // Execute begin method

  IAsyncResult ar = demoBeginRun(

  new AsyncCallback(outPut) state);

  // You can do other thins here

  // Wait until callback finished

  SystemThreadingThreadSleep();

  }

  // Callback method

  static void outPut(IAsyncResult ar)

  {

  bool state = (bool)arAsyncState;

  string demoName = demoEndRun(ar);

  if (state)

  {

  ConsoleWriteLine(demoName);

  }

  else

  {

  ConsoleWriteLine(demoName + isnt it?);

  }

  }

  }

  C#異步編程模式IAsyncResult的後話

  對於一個已經實現了 BeginOperationName 和 EndOperationName方法的對象我們可以直接用上述方式調用但對於只有同步方法的對象我們要對其進行異步調用也不需要增加對應的異步方法而只需定義一個委托並使用其 BeginInvoke 和 EndInvoke 方法就可以了

  C#異步編程模式IAsyncResult的基本情況就向你介紹到這裡希望對你了解和學習C#異步編程模式IAsyncResult有所幫助


From:http://tw.wingwit.com/Article/program/net/201311/11864.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.