良许Linux教程网 干货合集 .NET中的线程池的创建和使用

.NET中的线程池的创建和使用

线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。

使用ThreadPool来访问线程池

.NET中的线程池的创建和使用

这种做法可以让我们不用那么复杂的去实现创建,重用线程的逻辑,但是也有一些限制,比如由他内置的方法,我们不知道什么时候线程池里面的任务会结束,也不能获取线程的返回值。为了解决这些问题,微软引入了一个新的概念。

使用Task来访问线程池

引入了Task之后,你可以用如下实现来替代ThreadPool

img

这些实现都是等价的。Task本身实现了很多ThreadPool不能做的事情。

使用Task来获得线程的返回值

img

使用Task来等待线程结束

img

更多Task同步编程的使用,请参见(还没写,先给自己挖个坑O(∩_∩)O)。

异步委托

ThreadPool.QueueUserWorkItem没有提供一种简单的机制来获取线程的返回值。异步委托解决了这个问题,支持了传入一系列的参数。此外,异步委托中没有处理的异常会很方便的在调用线程的重新抛出(在调用EndInvoke的时候),因此不需要显示的处理。

通过异步委托来执行任务主要分一下几步:

  1. 初始化并声明一个你想要执行的委托
  2. 在委托上调用BeginInvoke,把返回值保存为IAsyncResult中

调用BeginInvoke不会阻塞当前线程,因此你可以在调用完之后执行其他你想要同步的操作

  1. 当你需要获取委托的返回值时,调用EndInvoke方法,把IAsyncResult传入EndInvoke中

阻塞的方式执行异步委托

img

EndInvoke主要做3件事: 1. 等待异步委托完成 2. 接收返回值 3. 把异步线程中未处理的异常在当前线程中重新抛出。

非阻塞的方式执行异步委托

你也可以在调用BeginInvoke的时候指定一个回调方法,这个方法会在异步委托结束的时候自动调用。这样异步委托就像是一个后台线程一样自动执行,不需要主线程等待。只需要在BeginInvoke的时候做一些额外的操作即可实现这种操作。

img

关于线程池

Jeffery在C# via CLR Chapter27中针对线程池的使用给出了一些建议。目前我们允许开发者来指定一个线程池的最大线程数。但是事实证明,我们往往不应该为一个线程池指定线程的上限,否则可能会出现程序死锁或者饿死的状态。比如你可能设置了1000个线程,但是某一时刻正好有第1001个线程需要等待所有线程结束才能执行,这种情况如果你限制了线程池线程的个数,就会出现死锁。从开发的另一个角度说,你也不应该限制一个进程使用多少资源,比如一个进程可以使用多少内存,使用多少带宽.因此虽然目前你可以通过GetMaxThreads, SetMaxThreads,GetMinThreads,SetMinThreads ,GetAvailableThreads来进行线程个数的限制,但是他仍然不建议大家这样做。这些限制可能会让你的程序运行的更慢。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

img
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部