VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • C#线程 入门(5)

 

(突出显示<string>类型的参数是为了清楚:如果我们省略它,则可以推断出它。)

查询包含在AggregateException中的任务的Result属性时,所有未处理的异常都会自动重新抛出。但是,如果您无法查询其Result属性(并且不调用Wait),则任何未处理的异常都会使该过程失败。

任务并行库具有更多功能,特别适合利用多核处理器。我们将在第5部分中继续讨论TPL。

不通过TPL进入线程池

如果目标是.NET Framework的早期版本(4.0之前),则不能使用任务并行库。相反,您必须使用一种较旧的结构来输入线程池:ThreadPool.QueueUserWorkItem和异步委托。两者之间的区别在于异步委托使您可以从线程返回数据。异步委托也将任何异常封送回调用方。

QueueUserWorkItem

要使用QueueUserWorkItem,只需使用要在池线程上运行的委托调用此方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
static void Main()
{
  ThreadPool.QueueUserWorkItem (Go);
  ThreadPool.QueueUserWorkItem (Go, 123);
  Console.ReadLine();
}
 
static void Go (object data)   // data will be null with the first call.
{
  Console.WriteLine ("Hello from the thread pool! " + data);
}
Hello from the thread pool!
Hello from the thread pool! 123

我们的目标方法Go必须接受单个对象参数(以满足WaitCallback委托)。就像使用ParameterizedThreadStart一样,这提供了一种将数据传递给方法的便捷方法。与Task不同,QueueUserWorkItem不会返回对象来帮助您随后管理执行。另外,您必须在目标代码中显式处理异常-未处理的异常将使程序瘫痪。

异步委托

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

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

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

  1. 实例化一个以您要并行运行的方法为目标的委托(通常是预定义的Func委托之一)。
  2. 在委托上调用BeginInvoke,保存其IAsyncResult返回值。     BeginInvoke立即返回给调用者。然后,您可以在池线程正在工作时执行其他活动。
  3. 当需要结果时,在委托上调用EndInvoke,传入保存的IAsyncResult对象。

在下面的示例中,我们使用异步委托调用与主线程并发执行,主线程是一种返回字符串长度的简单方法:

 

1
2
3
4
5
6
7
8
9
10
static void Main()
{
  Func<stringint> method = Work;
  IAsyncResult cookie = method.BeginInvoke ("test"nullnull);
  //
  // ... 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; }

  


相关教程
关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号