简体   繁体   English

.NET的多线程库

[英]Multi-threading libraries for .NET

I used multiple threads in a few programs, but still don't feel very comfortable about it. 我在一些程序中使用了多个线程,但仍然感觉不太舒服。

What multi-threading libraries for C#/.NET are out there and which advantages does one have over the other? C#/ .NET的多线程库有哪些,哪一个优于另一个?

By multi-threading libraries I mean everything which helps make programming with multiple threads easier. 通过多线程库,我的意思是一切有助于使多线程编程更容易。

What .NET integratet (ie like ThreadPool) do you use periodically? 你定期使用什么.NET集成(比如ThreadPool)? Which problems did you encounter? 你遇到了哪些问题?

There are various reasons for using multiple threads in an application: 在应用程序中使用多个线程有多种原因:

  • UI responsiveness UI响应
  • Concurrent operations 并发操作
  • Parallel speedup 并行加速

The approach one should choose depends on what you're trying to do. 应该选择的方法取决于你想要做什么。 For UI responsiveness, consider using BackgroundWorker , for example. 对于UI响应,请考虑使用BackgroundWorker

For concurrent operations (eg a server: something that doesn't have to be parallel, but probably does need to be concurrent even on a single-core system), consider using the thread pool or, if the tasks are long-lived and you need a lot of them, consider using one thread per task. 对于并发操作(例如服务器:东西不一定是平行的,但可能确实需要同时即使在单核系统),可以考虑使用线程池,或者,如果任务是长寿命和你需要很多,考虑每个任务使用一个线程。

If you have a so-called embarrassingly parallel problem that can be easily divided up into small subproblems, consider using a pool of worker threads (as many threads as CPU cores) that pull tasks from a queue. 如果你有一个所谓的令人尴尬的并行问题,可以很容易地分成小的子问题,那么考虑使用从队列中提取任务的工作线程池(与CPU核心一样多的线程)。 The Microsoft Task Parallel Library (TPL) may help here. Microsoft 任务并行库(TPL)可能会有所帮助。 If the job can be easily expressed as a monadic stream computation (ie with a query in LINQ with work in transformations and aggregations etc.), Parallel LINQ (same link) which runs on top of TPL may help. 如果作业可以很容易地表示为monadic流计算(即在LINQ中使用转换和聚合等工作进行查询),则在TPL之上运行的并行LINQ(相同链接)可能会有所帮助。

There are other approaches, such as Actor-style parallelism as seen in Erlang, which are harder to implement efficiently in .NET because of the lack of a green threading model or means to implement same, such as CLR-supported continuations. 还有其他方法,例如在Erlang中看到的Actor风格的并行性,由于缺少绿色线程模型或实现相同的方法(如CLR支持的延续),因此在.NET中难以有效实现。

查看Power Threading库。

I have written a lot of threading code in my days, even implemented my own threading pool & dispatcher. 在我的日子里,我编写了很多线程代码,甚至实现了我自己的线程池和调度程序。 A lot of it is documented here: 这里记录了很多内容:

http://web.archive.org/web/20120708232527/http://devplanet.com/blogs/brianr/default.aspx http://web.archive.org/web/20120708232527/http://devplanet.com/blogs/brianr/default.aspx

Just realize that I wrote these for very specific purposes and tested them in those conditions, and there is no real silver-bullet. 只是意识到我为了非常具体的目的编写了这些,并在这些条件下对它们进行了测试,并且没有真正的银弹。

My advise would be to get comfortable with the thread pool before you move to any other libraries. 我的建议是在移动到任何其他库之前熟悉线程池。 A lot of the framework code uses the thread pool, so even if you happen to find The Best Threads Library(TM), you will still have to work with the thread pool, so you really need to understand that. 很多框架代码都使用线程池,所以即使你碰巧找到了The Best Threads Library(TM),你仍然需要使用线程池,所以你真的需要理解它。

You should also keep in mind that a lot of work has been put into implementing the thread pool and tuning it. 您还应该记住,已经在实现线程池和调整它方面做了大量工作。 The upcoming version of .NET has numerous improvements triggered by the development the parallel libraries. 即将推出的.NET版本在开发并行库时引发了许多改进。

In my point of view many of the "problems" with the current thread pool can be amended by knowing its strengths and weaknesses. 在我看来,当前线程池的许多“问题”可以通过了解它的优点和缺点来修改。

Please keep in mind that you really should be closing threads (or allowing the threadpool to dispose) when you no longer need them, unless you will need them again soon. 请记住,当你不再需要它们时,你真的应该关闭线程(或允许线程池处理),除非你很快就会再次需要它们。 The reason I say this is that each thread requires stack memory (usually 1mb), so when you have applications sitting on threads but not using them, you are wasting memory. 我说这个的原因是每个线程需要堆栈内存(通常是1mb),所以当你有应用程序坐在线程上而不使用它们时,你就是在浪费内存。

For exmaple, Outlook on my machine right now has 20 threads open and is using 0% CPU. 例如,我的机器上的Outlook现在有20个线程打开并使用0%CPU。 That is simply a waste of (a least) 20mb of memory. 这只是浪费(至少)20mb的内存。 Word is also using another 10 threads with 0% CPU. Word也使用另外10个线程,0%CPU。 30mb may not seem like much, but what if every application was wasting 10-20 threads? 30mb可能看起来不多,但如果每个应用程序浪费10-20个线程怎么办?

Again, if you need access to a threadpool on a regular basis then you don't need to close it (creating/destroying threads has an overhead). 同样,如果您需要定期访问线程池,则无需关闭它(创建/销毁线程会产生开销)。

You don't have to use the threadpool explicitly, you can use BeginInvoke-EndInvoke if you need async calls. 您不必显式使用线程池,如果需要异步调用,可以使用BeginInvoke-EndInvoke。 It uses the threadpool behind the scenes. 它在幕后使用线程池。 See here: http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx 请参见此处: http//msdn.microsoft.com/en-us/library/2e08f6yc.aspx

You should take a look at the Concurrency & Coordination Runtime . 您应该查看并发和协调运行时 The CCR can be a little daunting at first as it requires a slightly different mind set. CCR最初可能有点令人生畏,因为它需要稍微不同的心态。 This video has a fairly good job of explanation of its workings... 这段视频对其工作原理进行了相当好的解释......

In my opinion this would be the way to go, and I also hear that it will use the same scheduler as the TPL . 在我看来,这将是要走的路,我也听说它将使用与TPL相同的调度程序。

For me the builtin classes of the Framework are more than enough. 对我来说,框架的内置类绰绰有余。 The Threadpool is odd and lame, but you can write your own easily. Threadpool是奇怪而蹩脚的,但你可以轻松编写自己的。

I often used the BackgroundWorker class for Frontends, cause it makes life much easier - invoking is done automatically for the eventhandlers. 我经常使用BackgroundWorker类作为Frontends,因为它使生活变得更加容易 - 为事件处理程序自动调用。

I regularly start of threads manually and safe them in an dictionary with a ManualResetEvent to be able to examine who of them has ended already. 我经常手动启动线程并使用ManualResetEvent将它们安全地保存在字典中,以便能够检查它们中的哪些已经结束。 I use the WaitHandle.WaitAll() Method for this. 我为此使用WaitHandle.WaitAll()方法。 Problem there is, that WaitHandle.WaitAll does not acceppt Arrays with more than 64 WaitHandles at once. 问题是,WaitHandle.WaitAll不会同时加入包含超过64个WaitHandles的数组。

You might want to look at the series of articles about threading patterns. 您可能希望查看有关线程模式的系列文章。 Right now it has sample codes for implementing a WorkerThread and a ThreadedQueue. 现在它有实现WorkerThread和ThreadedQueue的示例代码。

http://devpinoy.org/blogs/jakelite/archive/tags/Threading+Patterns/default.aspx http://devpinoy.org/blogs/jakelite/archive/tags/Threading+Patterns/default.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM