【发布时间】: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
}
}
【问题讨论】:
标签: c# database windows-services .net-2.0 ipc