使用C#安排函数在特定时间运行的最简单方法是什么?

时间:2011-11-18 14:04:08

标签: c# .net service scheduling

如果我想要发送的数据库中有很多消息,并且每行都指定了发送消息的日期和时间,以及是否已发送消息的标志。

这些并不总是固定的间隔,并且可能希望同时发送多条消息。

在这种情况下,它会将它们排队并按照创建时间顺序发送。

最简单的方法就是让一个功能一次又一次地运行,一旦完成就再次运行

所以它会:

  • 开始运行并检查当前日期/时间
  • 检查是否有未发送的消息
  • 发送所有在开始运行之前和之后发出的消息
  • 重新开始并采用当前日期/时间

我的问题是,持续运行方法只是非常低效,可能持续数小时或数天而不实际发送消息。

在这种情况下,我认为主要应变会放在数据库中,它会不断受到查询的影响。

是否有更好的方法来安排这样的事情发生。

或者只是执行上述操作,但每次运行时都会等待5分钟再重新运行。

Workflow 4是否提供了适合安排的任何内容?

13 个答案:

答案 0 :(得分:2)

你总是可以先对系列中的下一个时间值进行先发制人的读取,然后再进行一次睡眠,而不是一遍又一遍地进行短暂的睡眠。

不确定这是否像你想要的那样精致

答案 1 :(得分:1)

可能在数据库中有一个编译视图,它返回未发送的消息(我假设每条记录上都有一个标志?),并且预期的发送时间早于当前时间。然后,计划间隔的Windows服务或控制台应用程序可以访问该视图(可以很好地在数据库中进行性能调整,我想)并发送它返回的任何消息。

答案 2 :(得分:1)

您可以使用Windows服务来完成此任务。或者,如果您使用的是MSSQL,您甚至可以使用SQL Server代理作业。

答案 3 :(得分:1)

有几个答案建议发送一些消息,然后调用 sleep ,直到下一条消息发送为止。

在这种情况下你如何睡觉都很重要。

理论上,您可以告诉线程休眠几个小时,但是如果在此期间应用程序(或服务)需要关闭,那么您就遇到了麻烦。该过程将终止,不会执行清理。这不太理想。

不要混淆民意调查的概念,以及民意调查之间的睡眠

如果您要在下次轮询数据库之前等待5分钟(或5小时),那很好,但是您不希望* 睡眠一次超过一两秒钟。

我要做什么。 。

编写Windows服务。该服务有一个活动线程来轮询数据库,请参阅发送的任何消息,然后发送它们。 然后它会以可配置的延迟进行轮询(1分钟,5分钟,1小时,什么都适合) 但是,在等待轮询数据库时,它将永远不会睡眠超过一秒钟。

如果可以放心,只能在数据库中的最后一条消息之后添加消息?如果是这样,您可以检查下一条消息的时间,直到那时才进行轮询。

但是,如果我发现下一条消息不需要发送5小时,是否可能在我等待的时候添加了应该在30分钟内发送的消息? 如果是这样,那么你永远不会相信“下一个消息时间”并且在此之前不会进行投票,你必须继续轮询你的固定间隔 NB 值得再说一遍,你的轮询间隔和你的睡眠间隔不是一回事。

答案 4 :(得分:0)

如何编写为您执行此操作的Windows服务。此Windows服务将在后台运行,并在特定时间间隔内检查当前时间与您的数据库记录(例如:每5分钟)并向人们发送电子邮件并更新表中的相应记录以将电子邮件发送标记设置为真

您甚至可以拥有一个SQL作业,该作业选择未发送的记录并与当前时间匹配,并调用调用dot net assembly发送电子邮件的存储过程。点网组件可以使用SMTPClient发送电子邮件。

答案 5 :(得分:0)

这取决于你使用的是什么。对于您描述的方案,使用计划任务或服务是完全可以接受的。

如果进程过于频繁,您不必占用资源,但必须小心。它可能更有效率,在高峰时段运行频率较低,而在非高峰时段运行频率更低。

答案 6 :(得分:0)

无论您喜欢哪种方法(制作Windows服务,使用任务计划程序等等),请记住您的初步建议正是所谓的busy waiting,这是您应该避免的,除非您真的知道你在做什么。

答案 7 :(得分:0)

如果你延长它,你所描述的并不是那么糟糕 “当没有消息到期时,选择下一次消息到期并睡到那时”。

或者使用带有“通知支持”的数据库,使事件驱动整个事件,即每当消息到期时,数据库都会向您发送事件。

答案 8 :(得分:0)

我最近实现了一个Windows服务,该服务在C5集合类库中使用了一个名为IntervalHeap的类。然后,我添加了一个持久层,用于保存项目及其间隔的跟踪,以防服务停止/崩溃。

已经生产了几个月并且一直很好。

答案 9 :(得分:0)

您可以使用此.NET Scheduled Timer来检查时间间隔并以特定时间间隔运行功能(发送消息)....

答案 10 :(得分:0)

我想说用计时器创建一个Windows服务。它可以睡眠配置的秒数,然后比较数据库中的日期时间。如果匹配则发送电子邮件&在数据库中设置发送电子邮件的标志。

答案 11 :(得分:0)

我们在金融机构这样做,从内部网应用程序发送内部电子邮件。每15分钟一次,调度软件(企业调度程序,而不是Windows计划任务)会触发作业。我们在名为PendingEmail的表格上有一个名为EmailQueue的视图,该视图仅列出了需要发送的内容(EmailQueue表格有PopDate,是关于何时发送电子邮件的生效日期)。该应用程序会发送电子邮件,以查看PendingEmails视图中的任何内容。

作业每15分钟发送一次最大批量电子邮件,标记每条记录是否已成功发送,或者是否有错误(无效的电子邮件地址等)以及Exception是什么,以及我们是否愿意在下次尝试重新发送它。它一次更新EmailQueue表,而不是单独更新每个记录。批量大小已经到位,以防止工作时间超过15分钟并且自行踩踏。

我不知道每隔一段时间进行一次投票就会消耗掉所有这么多资源,除非你每隔5秒钟做一次这样的事情。如果您要发送数百万条消息,则可能需要跨多台计算机分发作品。如果您要编写一些自定义代码,我会使用Timer而非Thread.Sleep(),并将Timer设置为每5分钟或您希望执行工作的任何时间间隔。每个勾选都会触发一个事件,以便启动发送消息的例程。

Thread.Sleep()Timer班级

上查看此帖子

答案 12 :(得分:0)

许多数据库允许触发器触发事件​​,例如。 '插入后'。触发器由数据库进程/线程运行,它可以采取的操作是特定于数据库的。例如,它可以调用一个C或java过程来指示您的电子邮件正在等待或执行的命名信号量。直接的电子邮件应用程序。查看数据库的“触发器”或“创建触发器”。