在我的应用程序中,我有一组插件 - 在应用程序中发生某些事件时执行一些小操作的类。插件的每个方法都必须在一个单独的线程中调用,尽管每个插件只能同时运行一个方法。
我可以通过两种方式实现这一点:
为每个插件创建单个线程,该插件将处理插件队列中的事件,直到队列为空。然后睡觉直到新事件排队,处理它等等。
当事件进入插件的队列时,它会在线程池线程中处理它。当队列变空时,将其释放回线程池。
问题是:这两种方式有哪些优点和缺点?
一些澄清:
答案 0 :(得分:2)
插件的每个方法都必须在一个单独的线程中调用,尽管每个插件只能同时运行一个方法。
如果这是您的要求,我会考虑围绕BlockingCollection<T>
构建插件。添加插件时,请启动一项长期运行的任务,该任务仅在foreach
上执行BlockingCollection.GetConsumingEnumerable()
。
这将允许您将项目添加到其“队列”,并且插件将按顺序自动处理这些项目,而无需您自己的“睡眠”处理。每个插件都可以使用blockingCollection.GetConsumingEnumerable
来处理其队列中的项目。
答案 1 :(得分:1)
我看到过两种方式。每个插件一个线程变得丑陋的是 - 你开始依赖于“只有一个线程触及我的插件”的想法,然后有人在一个插件的线程进入并触及其他插件时犯了错误(虽然复杂的事件处理或类似的东西)。然后你最终会遇到非常难以追踪的比赛条件。
@ Reed-Copsey建议的方法要简洁得多,但是如果你必须使用你提到的两种方法之一,那么使用线程池并适当锁定将为你节省一些心痛。如果您有多个团队成员在项目的多个方面工作,这尤其适用。
答案 2 :(得分:1)
我会选择#2。原因是你没有保留大部分时间闲置的大量线程。这样做真的没有缺点,因为你也可以获得不同插件和每个给定插件的顺序执行之间的并行性。