C#线程 入门-异步委托

异步委托
ThreadPool.QueueUserWorkItem没有提供一种简单的机制来在线程执行完毕后从线程取回返回值。异步委托调用(简称异步委托)解决了这一问题,允许在两个方向上传递任意数量的类型化参数。此外,异步委托上未处理的异常可以方便地在原始线程(或更准确地说是调用EndInvoke的线程)上重新抛出,因此不需要显式处理。

不要将异步委托与异步方法(以Begin或End开头的方法,例如File.BeginRead / File.EndRead)混淆。异步方法在外部遵循类似的协议,但是它们存在是为了解决更难的问题,我们将在C#4.0的第23章“简而言之”中进行描述。

通过异步委托启动工作任务的方法如下:

实例化一个以您要并行运行的方法为目标的委托(通常是预定义的Func委托之一)。
在委托上调用BeginInvoke,保存其IAsyncResult返回值。 BeginInvoke立即返回给调用者。然后,您可以在池线程正在工作时执行其他活动。
当需要结果时,在委托上调用EndInvoke,传入保存的IAsyncResult对象。
在下面的示例中,我们使用异步c#教程委托调用与主线程并发执行,主线程是一种返回字符串长度的简单方法:

 
static void Main()
{
  Func<string, int> method = Work;
  IAsyncResult cookie = method.BeginInvoke ("test", null, null);
  //
  // ... here's where we can do other work in parallel...
  //
  int result = method.EndInvoke (cookie);
  Console.WriteLine ("String length is: " + result);
}
static int Work (string s) { return s.Length; }
  

EndInvoke做三件事。首先,它会等待异步委托vb.net教程完成执行(如果尚未执行)。其次,它接收返回值(以及任何ref或out参数)。第三,它将所有未处理的工作程序异常抛出回调用线程。

如果您使用异步委托调用的方法没有返回值,则仍然(在技术上)有义务调用EndInvoke。实际上,这是有争议的。没有EndInvoke警察对违规者进行处罚!但是,如果您选择不调用EndInvoke,则需要考虑worker方法上的异常处理,以避免无提示的失败。

您还可以在调用BeginInvoke时指定一个回调委托-一种接受IAsyncResult对象的方法,该方法在完成后会自动调用。这允许煽动线程“忘记”异步委托,但是在回调端需要一些额外的工作:

static void Main()
{
  Func<string, int> method = Work;
  method.BeginInvoke ("test", Done, method);
  // ...
  //
}
 
static int Work (string s) { return s.Length; }
 
static void Done (IAsyncResult cookie)
{
  var target = (Func<string, int>) cookie.AsyncState;
  int result = target.EndInvoke (cookie);
  Console.WriteLine ("String length is: " + result);
}
Be

ginInvoke的最后一个参数是填充IAsyncResult的AsyncState属性的用户状态对象。它可以包含您喜欢的任何内容;在这种情况下,我们使用它将方法委托传递给完成回调,因此我们可以在其上调用EndInvoke。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值