需要:从数据库中的作业队列执行作业的Windows服务; 通缉:示例代码

Jim*_* G. 6 .net c# windows-services sample

需要:

  • 从数据库中的作业队列执行作业的Windows服务

通缉:

  • 此类应用程序的示例代码,指南或最佳实践

背景:

  • 用户将单击将向行中插入行的ashx链接.
  • 我需要我的Windows服务定期轮询此表中的行,它应该为每一行执行一个工作单元.

重点:

  • 这对我来说并不是一个全新的领域.
    • 编辑:您可以假设我知道如何创建Windows服务和基本数据访问.
  • 但我需要从头开始编写这项服务.
  • 而且我只想提前知道我需要考虑的事项.
  • 编辑:我最担心失败的工作,争夺工作,以及保持服务运行.

Rem*_*anu 8

鉴于您正在处理数据库队列,由于数据库的事务性质,您可以公平地完成已经完成的工作.典型的队列驱动应用程序有一个循环:

while(1) {
 Start transction;
 Dequeue item from queue;
 process item;
 save new state of item;
 commit;
}
Run Code Online (Sandbox Code Playgroud)

如果处理在中途崩溃,则事务回滚并在下次服务启动时处理该项目.

但实际上,在数据库中写入队列是很多棘手比你相信.如果你部署一个天真的方法,你会发现你的入队和出队相互阻塞,ashx页面变得没有响应.接下来你会发现dequeue与dequeue都是死锁,你的循环经常遇到错误1205.我强烈建议你阅读本文使用Tables as Queues.

您的下一个挑战是如何将汇集率"恰到好处".过于激进,您的数据库将从池化请求中炙手可热.太麻烦了,你的队列会在高峰期增长,而且排水太慢.您应该考虑使用完全不同的方法:使用SQL Server内置QUEUE对象并依赖WAITFOR(RECEIVE)语义的魔力.这允许完全轮询免费的自我调整服务行为.实际上,还有更多:您不需要服务开始.有关我正在谈论的内容的解释,请参阅异步过程执行:以完全可靠的方式从Web服务调用在SQL Server中异步启动处理.最后,,允许处理在独立进程中托管,而不是T-SQL过程.


Chr*_*ris 1

根据您的编辑,我能想到的一些事情:

回复:工作失败:

  • 确定作业是否可以重试并执行以下操作之一:
    • 将行移至“错误”表以便稍后记录/报告或
    • 将该行留在队列中,以便作业服务重新处理它
    • 您可以添加诸如 WaitUntil 之类的列或类似于在失败后延迟重试作业的列

回复:争论:

  • 添加时间戳列(例如“JobStarted”或“Locked”)以跟踪作业的启动时间。这将防止其他线程(假设您的服务是多线程的)尝试同时执行作业。
  • 您需要有一些清理过程来完成并清除过时的作业以进行重新处理(如果作业服务失败并且您的锁永远不会被释放)。

回复:保持服务运行

  • 如果服务失败,您可以告诉 Windows 重新启动该服务。
  • 您可以通过在服务运行时保持某种文件打开并在成功关闭时将其删除来检测启动时以前的故障。如果您的服务启动并且该文件已经存在,您就知道该服务之前失败了,并且可以提醒操作员或执行必要的清理操作。

我真的只是在黑暗中摸索。我强烈建议对服务进行原型设计,并返回有关其运作方式的任何具体问题。