C#异步编程模式IAsyncResult概述

 我来答
华源网络
2022-10-04 · TA获得超过5597个赞
知道小有建树答主
回答量:2486
采纳率:100%
帮助的人:147万
展开全部

  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_Delegate BeginInvoke(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 can t be null );

  try

  {

  return m_Delegate EndInvoke(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 = demo BeginRun(null null);

  // You can do other things here

  // Use end method to block thread

  // until the operation is plete

  string demoName = demo EndRun(ar);

  Console WriteLine(demoName);

  }

  }

  也可以用 IAsyncResult 的 AsyncWaitHandle 属性 我在这里设置为 秒超时

  class AsyncTest

  {

  static void Main(string[] args)

  {

  AsyncDemo demo = new AsyncDemo( jiangnii );

  // Execute begin method

  IAsyncResult ar = demo BeginRun(null null);

  // You can do other things here

  // Use AsyncWaitHandle WaitOne method to block thread for second at most

  ar AsyncWaitHandle WaitOne( false);

  if (ar IsCompleted)

  {

  // Still need use end method to get result

  // but this time it will return immediately

  string demoName = demo EndRun(ar);

  Console WriteLine(demoName);

  }

  else

  {

  Console WriteLine( Sorry

  can t 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 = demo BeginRun(null null);

  Console Write( Waiting );

  while (!ar IsCompleted)

  {

  Console Write( );

  // You can do other things here

  }

  Console WriteLine();

  // Still need use end method to get result

  //but this time it will return immediately

  string demoName = demo EndRun(ar);

  Console WriteLine(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 = demo BeginRun(

  new AsyncCallback(outPut) state);

  // You can do other thins here

  // Wait until callback finished

  System Threading Thread Sleep( );

  }

  // Callback method

  static void outPut(IAsyncResult ar)

  {

  bool state = (bool)ar AsyncState;

  string demoName = demo EndRun(ar);

  if (state)

  {

  Console WriteLine(demoName);

  }

  else

  {

  Console WriteLine(demoName + isn t it? );

  }

  }

  }

  C#异步编程模式IAsyncResult的后话

  对于一个已经实现了 BeginOperationName 和 EndOperationName方法的对象 我们可以直接用上述方式调用 但对于只有同步方法的对象 我们要对其进行异步调用也不需要增加对应的异步方法 而只需定义一个委托并使用其 BeginInvoke 和 EndInvoke 方法就可以了

lishixinzhi/Article/program/net/201311/11864

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式