Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何仅让程序的一个实例运行计划任务?_C#_Multithreading_Scheduled Tasks - Fatal编程技术网

C# 如何仅让程序的一个实例运行计划任务?

C# 如何仅让程序的一个实例运行计划任务?,c#,multithreading,scheduled-tasks,C#,Multithreading,Scheduled Tasks,我的软件在多台计算机上针对单个数据库运行 我想每天在软件中执行一项任务-例如中午 我如何确保此任务是: 每天只表演一次 无论哪台机器/用户恰好在当天运行软件,都会执行此操作,并且 未与软件的任何其他实例同时执行 在客户端执行此操作的问题是,您的用户可能一天都没有运行软件,或者在操作过程中可能遇到硬件故障(例如断电),导致永久锁定行。您无法保证任务的完整性,甚至无法保证任务将运行 如果您需要确保无论用户是否每天实际使用您的软件,它都能运行,这将有助于在数据库服务器上执行计划任务(可用于和) 创建

我的软件在多台计算机上针对单个数据库运行

我想每天在软件中执行一项任务-例如中午

我如何确保此任务是:

  • 每天只表演一次
  • 无论哪台机器/用户恰好在当天运行软件,都会执行此操作,并且
  • 未与软件的任何其他实例同时执行

在客户端执行此操作的问题是,您的用户可能一天都没有运行软件,或者在操作过程中可能遇到硬件故障(例如断电),导致永久锁定行。您无法保证任务的完整性,甚至无法保证任务将运行

如果您需要确保无论用户是否每天实际使用您的软件,它都能运行,这将有助于在数据库服务器上执行计划任务(可用于和)

创建一个执行任务的可执行文件,然后创建一个计划任务以每天运行它。这样,只要数据库机器处于运行状态,您就可以得到一个始终运行的实例,并且不必担心跨客户端跟踪作业执行


好的,您现在是说,由于公司规则,您不能在数据库框上运行计划任务。以下是我将使用的方案:

  • 为作业调度创建一个表。为每个作业指定运行的日期/时间、作业开始的时间(如果未开始,则为null)、进度字段以及任务所需的名称和其他信息
  • 让每个客户端每隔5分钟左右进行一次轮询,以运行查询以查找日期在过去的作业。选择行未锁定的第一个作业
  • 锁定行并将“作业开始时间”字段更新为当前时间
  • 执行任务,将进度字段更新为作业完成的一部分
  • 成功时删除该行,否则将该行标记为“失败”

  • 重要的部分是“作业开始时间”字段,该字段允许客户端检查作业是否在很久以前(例如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小时来完成(!!),您将只有一个实例执行该任务。不能在任务计划程序中。某些企业环境不允许在其系统上创建此类任务。