.Net 2.0 Windows 服务进程通信:数据库还是 IPC?
Posted
技术标签:
【中文标题】.Net 2.0 Windows 服务进程通信:数据库还是 IPC?【英文标题】:.Net 2.0 Windows Service Process Communication: Database or IPC? 【发布时间】:2009-07-02 14:25:45 【问题描述】:我有一个在 .Net 2.0 环境中运行的 Windows 服务(不能升级到 3/3.5)。 该服务在 X 秒间隔上使用 System.Timers.Timer 轮询数据库表上的项目。
Timer.Elapsed 事件处理代码包裹在 lock 语句周围,以防止在前一个处理尚未完成时运行下一个 Elapsed 事件。对于每个项目,执行流程 A,然后从数据库中删除该项目。这是当前的“生产”代码。
需要执行第二个进程(进程 B),但仅针对某些项目(我可以使用条件轻松隔离)并且仅在进程 A 处理它们之后。用于运行进程 B 的资源一次只接受一个连接。 (因此,不能选择为每个 Process B 执行多个线程)如果我要在 Timer.Elapsed 事件处理代码和 Process A 上运行 Process B,这将大大延迟事件处理程序的执行并使其更有可能Elapsed 事件将无法及时完成下一个事件的执行,从而使系统响应速度变慢等。
我认为最好让一个新的单线程执行进程 B(或其他服务,我认为这会有点过分)。进程 A 会为进程 B 排队项目,因此如果进程 B 完成处理项目的时间比进程 A 长,那么下一次进程 A 运行只会将更多项目添加到进程 B 队列中。
我知道使用数据库作为 IPC 并不是一个很好的做法,但考虑到我不能使用 WCF IPC(这可能是我的方法)并且我已经在这里使用了数据库。 ..
如果我继续使用数据库作为我的 IPC 机制并在进程 A 完成后标记数据库上的项目以便进程 B 可以选择和处理它们(包括删除)?还是应该尝试在线程之间使用某种直接 IPC?
如果系统崩溃或服务关闭,我保证队列中的项目将持续存在,这一点非常重要。
//This is how my Elapsed event handler should look
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
lock(this)
//Load items from DB
//foreach item
//Run Process A
//if(item.Member == condition)
// Queue item for Process B (DB = reflag, IPC = send message)
//If using IPC delete the item from the DB
【问题讨论】:
【参考方案1】:除了在 timer_elapsed 中使用“锁定”之外,您可以禁用/启用计时器吗?在开始时禁用计时器,然后在“最终”中启用计时器。这样您就不必担心重叠事件。
如果这不是一个选项并且计时器必须在每个间隔触发,无论处理如何,然后在数据库中标记该项目并使用两个计时器。一个计时器用于“进程 A”,一个计时器用于“进程 B”。
【讨论】:
【参考方案2】:相反,由于您在问题末尾提到的共同要求,使用数据库作为您的进程间通信渠道是一种了不起的做法:
我很重要 保证队列中的项目 如果系统崩溃或 服务已关闭。
只需确保标记发生在与进程 A 进行的任何其他数据更改相同的事务范围内。
您甚至可以考虑将其拆分为两个服务,并在逻辑进程 A 和 B 之间使用 MessageQueue
。
【讨论】:
以上是关于.Net 2.0 Windows 服务进程通信:数据库还是 IPC?的主要内容,如果未能解决你的问题,请参考以下文章
为应用程序池“应用程序池”提供服务的进程与 Windows 进程激活服务发生了致命的通信错误