C# 如何仅让程序的一个实例运行计划任务?
我的软件在多台计算机上针对单个数据库运行 我想每天在软件中执行一项任务-例如中午 我如何确保此任务是:C# 如何仅让程序的一个实例运行计划任务?,c#,multithreading,scheduled-tasks,C#,Multithreading,Scheduled Tasks,我的软件在多台计算机上针对单个数据库运行 我想每天在软件中执行一项任务-例如中午 我如何确保此任务是: 每天只表演一次 无论哪台机器/用户恰好在当天运行软件,都会执行此操作,并且 未与软件的任何其他实例同时执行 在客户端执行此操作的问题是,您的用户可能一天都没有运行软件,或者在操作过程中可能遇到硬件故障(例如断电),导致永久锁定行。您无法保证任务的完整性,甚至无法保证任务将运行 如果您需要确保无论用户是否每天实际使用您的软件,它都能运行,这将有助于在数据库服务器上执行计划任务(可用于和) 创建
- 每天只表演一次
- 无论哪台机器/用户恰好在当天运行软件,都会执行此操作,并且
- 未与软件的任何其他实例同时执行
好的,您现在是说,由于公司规则,您不能在数据库框上运行计划任务。以下是我将使用的方案:
重要的部分是“作业开始时间”字段,该字段允许客户端检查作业是否在很久以前(例如3小时)开始但从未完成,因此可以重试作业或向用户发出警报,具体取决于进度值。您可以在数据库中使用具有单行的表。使用事务锁定包含上次更新日期的行 每X分钟:
- 如果记录被锁定,则表示有人正在执行作业。什么也不做
- 如果记录已过期且未锁定,请锁定它并执行此操作。如果失败,请解锁记录。如果成功,则使用当前日期更新记录
- 如果记录包含当前日期,则不执行任何操作
使用SQL Server的示例 如果在事务中运行此操作,它将锁定来自其他客户端的行
UPDATE Test WITH (ROWLOCK)
SET UpdateDate = yourDate
WHERE PrimaryKey = yourkey
如果有一天没有人运行该软件呢?为什么不使用自定义列作为锁来跟踪数据库中作业的执行情况,以避免再次执行?@polyman:如果发生这种情况,那就太糟糕了。我无能为力。@CraigJ所以你的客户每次有培训日、团队建设日或圣诞节假期有很多员工休假时都必须开具支持票?听起来不太理想。@CraigJ对于一个好客的人来说,这听起来需要很多努力和复杂性。在数据库盒上运行cronjob或计划任务的障碍是什么?如果有一天没有人运行该软件?或者如果机器在锁定行后发生电源故障?您所说的“锁定行”是什么意思?事务不会锁定行。在事务中运行时,电源故障不应该是问题。如果没有人运行软件,那么,嗯,没有人运行软件…;-)@CraigJ我已经更新了我的answer@JohannBlais:另一种选择是,因为我认为我的数据库服务器不会接受该SQL,我可以只使用一个名为“LOCKED”的字段并将其设置为true吗?我使用的数据库没有这样的功能。必须在软件中完成。数据库不提供任务计划程序。它是操作系统的一部分。在Windows上,可以使用任务计划程序。在Linux上,您可以使用cron。同意,这必须由操作系统控制,而不是由应用程序本身控制。在Windows计划任务(不确定cron作业)中,有一个特定的功能只允许任务的单个进程。@Terric cron作业只运行一个命令,因此cron作业看起来像“每天下午3点运行此命令”。只要该命令不花费>24小时来完成(!!),您将只有一个实例执行该任务。不能在任务计划程序中。某些企业环境不允许在其系统上创建此类任务。