.NET的多线程库

10

我在一些程序中使用了多个线程,但仍然不太熟悉它。

C#/.NET有哪些多线程库?它们之间有什么优劣势?

通过多线程库,我指的是一切可以帮助简化多线程编程的工具。

在.NET集成中,你定期使用哪些(例如线程池)?遇到了哪些问题?

10个回答

12

使用多线程的应用有各种原因:

  • UI响应性
  • 并发操作
  • 平行加速

选择何种方法取决于你试图做什么。例如,考虑使用 BackgroundWorker 来实现UI响应性。

对于并发操作(例如服务器:即使在单核系统上也可能需要并发,但不一定要并行),可以考虑使用线程池或者如果任务是长期存在且你需要大量的任务,可以考虑每个任务使用一个线程。

如果有所谓的“尴尬的”可轻松将问题分成小子问题的问题,请考虑使用工作线程池(与CPU内核数量相同的许多线程从队列中提取任务)。 Microsoft 的任务并行库(TPL) 可以帮助您解决这个问题。如果该工作可以轻松地表示为Monad流计算(即在LINQ查询中具有转换和聚合工作等),则运行在TPL之上的Parallel LINQ(相同链接)可能有所帮助。

还有其他方法,例如Erlang中看到的Actor-style parallelism,由于.NET缺乏绿色线程模型或者实现同样的CLR支持的连续性,这些方法在.NET上实现难度较大。


我过去曾经成功地使用过TPL——就线程而言,它非常容易上手。 - Jon Adams

3

2

Power Threading库非常酷,但我不会在生产代码中使用它的某些功能,因为它利用了一些编译器模式,这些模式不能保证在将来的.NET版本中得到维护。 - Brian Rudolph

2

1

我的建议是在转向其他库之前,先熟悉线程池。许多框架代码都使用线程池,因此即使您找到了最好的线程库,仍然需要使用线程池,因此您真的需要理解它。

您还应该记住,已经投入了大量工作来实现和调整线程池。 .NET 的即将推出的版本有许多改进,这些改进是由并行库的开发触发的。

在我看来,许多当前线程池的“问题”可以通过了解其优点和缺点来解决。


“…了解其优点和缺点。” 正如问题中所问,你遇到了哪些问题。我仍然相信一个人不必犯错误才能学习,我也尝试从别人的错误中学习。 - Xn0vv3r

1
请记住,当您不再需要线程时,您真的应该关闭它们(或允许线程池进行处理),除非您很快会再次需要它们。我这么说的原因是每个线程都需要堆栈内存(通常为1mb),因此当您有应用程序坐在线程上但不使用它们时,您正在浪费内存。
例如,我的计算机上的Outlook现在打开了20个线程,并且未使用CPU。这只是浪费了至少20mb的内存。Word还使用另外10个线程,CPU使用率为0%。30mb可能看起来不像什么,但如果每个应用程序都浪费了10-20个线程呢?
同样,如果您需要定期访问线程池,则无需关闭它(创建/销毁线程会产生开销)。

不要浪费内存 - 浪费虚拟地址空间。在Windows上,大多数语言在线程创建时保留1MB的堆栈空间,但是它会使用特殊的页面保护(一个守卫页)按需提交。 - Barry Kelly
内存在需要时才被提交,这是没错,但当它不再需要时,它会被清理吗?我的问题不在于创建线程并不使用它们,而是将它们用于短期任务并在不再需要时不处理它们。 - Richard Szalay

1

1
你应该看看并发和协调运行时。CCR 可能会在一开始有点让人望而生畏,因为它需要稍微不同的思维方式。这个视频对其工作原理进行了相当好的解释……
我认为这是前进的方式,我还听说它将使用与TPL相同的调度程序。

0

0

对我来说,框架内置的类已经足够了。虽然Threadpool有点奇怪和无聊,但你可以很容易地编写自己的线程池。

我经常在前端使用BackgroundWorker类,因为它使生活变得更加轻松 - 调用事件处理程序时会自动完成。

我经常手动启动线程,并使用ManualResetEvent将其保存在字典中,以便能够检查哪些线程已经结束。我使用WaitHandle.WaitAll()方法来实现这一点。问题在于,WaitHandle.WaitAll一次不接受超过64个WaitHandles的数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接