处理C#4中后台线程中引发事件的工作负载并控制线程数

时间:2012-07-20 08:12:36

标签: multithreading c#-4.0 event-handling backgroundworker task-parallel-library

我有一个C#4应用程序正在订阅一个事件,我希望它会连续快速地被提升很多次。每次引发都需要做一些工作,我真的不想阻止事件线程。

感觉我应该将这个“块”工作传递给后台线程/任务并允许事件线程继续,但是我还需要确保没有创建太多线程,就像我说的那样,我希望这个事件很快就会被提升很多次。

是否存在可识别的模式或推荐方法,用于将事件处理程序工作负载传递给后台线程但限制创建的线程数量?

感觉应该有一些使用任务并行库的方法,但是找不到我现在需要的任何东西。

如果有人需要更多信息,请告诉我,因为我感谢我对我所说的内容非常一般。

感谢。

3 个答案:

答案 0 :(得分:1)

在应用运行期间不要创建任何线程。当事件触发并将它们提交/排队到线程池时,创建(或depool)任务。

如果你没有动手创建任何线程,(除了在服务线程池的服务器启动时),你就不能创建太多的线程!

你可以创建太多的任务,但还有其他机制可以限制它,(我通常在启动时创建固定数量的任务,但是比线程数多很多,并将它们集中在BlockingCollection中,弹出/ loading / submitting / puishingBack在运行期间,因此提供数据/任务流控制。)

答案 1 :(得分:1)

如果每次引发事件时要执行的“工作量”很小且主要受CPU限制,那么每次只需启动TaskThreadPool将确定要使用的最佳线程数,这很可能接近您拥有的CPU核心数。在这种情况下,您不必担心限制并行度。

如果每次加注的工作需要很长时间,或者它主要是IO绑定的,那么您应该手动限制并行度。一种方法是使少量线程在没有工作时阻塞,否则从队列中处理事件。您可以使用BlockingCollection来实现此目的。

如果您可以使用.Net 4.5,可能是最好的选择是使用来自TPL Dataflow的ActionBlock并设置MaximumDegreeOfParallelism。有了它,你就不会在没有工作时浪费任何线程,你可以设置使用(或不使用)的最大线程数。

答案 2 :(得分:0)

ActionBlock和TPL数据流的其余部分也可以以CTP的形式用于.NET 4 - 对于主要场景它是可靠的(我在一个大型项目中使用CTP没有任何问题 - 当然你的里程数可能会有所不同)

如果您在调用远程Web服务后需要完成其他工作(例如:整理结果,更新日志),数据流块甚至可以让您创建管道

相关问题