C# 如何在每天给定的时间执行代码?

C# 如何在每天给定的时间执行代码?,c#,datetime,time,timezone,C#,Datetime,Time,Timezone,我试图在我的程序中添加一个功能,在芝加哥期货市场收盘后每天都会执行代码。这意味着我希望在东部时间5:35左右(市场所在地的中部时间4:35)运行代码。当然,随着夏令时的到来,这将在东部标准时间(UTC-5)和东部标准时间(UTC-4)之间来回切换 我知道有很多类似的问题,但是没有一个能提供我可以使用的解决方案。主要的建议似乎是使用任务调度器或Quartz,但是,我无法在我的程序中实现这些。我认为最有希望的解决方案是结合使用TimeZoneInfo、DateTime和TimeSpan来安排每天在正

我试图在我的程序中添加一个功能,在芝加哥期货市场收盘后每天都会执行代码。这意味着我希望在东部时间5:35左右(市场所在地的中部时间4:35)运行代码。当然,随着夏令时的到来,这将在东部标准时间(UTC-5)和东部标准时间(UTC-4)之间来回切换

我知道有很多类似的问题,但是没有一个能提供我可以使用的解决方案。主要的建议似乎是使用任务调度器或Quartz,但是,我无法在我的程序中实现这些。我认为最有希望的解决方案是结合使用
TimeZoneInfo
DateTime
TimeSpan
来安排每天在正确时间触发的计时器。我目前的解决方案是:

    DateTime now = DateTime.Now;
    DateTime currentDateTime = now.DateTime.Date;
    DateTime expiryDateTime = currentDateTime
        .AddHours(17)
        .AddMinutes(35)
        .AddDays(
            now.DateTime.Hour >= 18 + utcOffset 
            || (now.DateTime.Hour == 17 && now.DateTime.Minute >= 35) ? 1 : 0);
    Timer timer = new Timer(
         ...,
         null,
         expiryDateTime - DateTime.Now,
         ...);
但是,如果我的代码在东部时间以外的时区运行,我认为这会崩溃。我还担心,当时区从美国东部标准时间切换到美国东部标准时间(EST)或visa国际组织(visa)从美国东部标准时间切换到美国东部标准时间(visa国际组织)时,在23小时或25小时的工作日内,这种情况不会正常发生

有没有比我现在做的更好的方法来处理日程安排?如何使这段代码更健壮,以处理在任何时区运行但始终在东部时间同时执行的情况


编辑:如上所述,任务计划程序和Quartz不是选项。Quartz已退出,因为我无法包含第三方库。任务调度程序已退出,因为我需要从程序访问许多内部值。启动另一个应用程序并将这些值公开给该应用程序会增加比我认为的更大的复杂性

设置windows计划任务。对于这样一个简单的任务,长时间运行的计时器往往会有问题,而且肯定过于复杂。

设置windows计划的任务。对于这样一个简单的作业,长时间运行的计时器往往是有问题的,而且肯定过于复杂。

使用任务调度框架,如

使用任务调度框架,如

您缺少Windows任务调度程序的要点。您不在应用程序中实现它。您可以编写一个应用程序,然后使用任务调度器在每天设定的时间运行它

不幸的是,在回答您关于日程安排和应用程序性质的澄清时,您强调需要重新考虑您的应用程序。构建一个必须一直运行并且不断添加功能的整体式应用程序不是一个好主意


相反,为什么不重新考虑应用程序的结构呢。您可以拥有核心功能,它需要一直作为服务运行。然后,其他组件可以通过restful接口与之通信。然后可以停止和启动应用程序的用户界面,而不必担心影响服务,因为服务可以继续运行。此外,添加额外的功能,例如在一天中的特定时间执行特定TSAK的计划应用程序,变得更加容易。

您缺少Windows任务计划程序的要点。您不在应用程序中实现它。您可以编写一个应用程序,然后使用任务调度器在每天设定的时间运行它

不幸的是,在回答您关于日程安排和应用程序性质的澄清时,您强调需要重新考虑您的应用程序。构建一个必须一直运行并且不断添加功能的整体式应用程序不是一个好主意


相反,为什么不重新考虑应用程序的结构呢。您可以拥有核心功能,它需要一直作为服务运行。然后,其他组件可以通过restful接口与之通信。然后可以停止和启动应用程序的用户界面,而不必担心影响服务,因为服务可以继续运行。此外,添加额外的功能,例如在一天中的特定时间执行特定TSAK的计划应用,变得更加容易。

您可以创建Windows服务并将其安装到您的系统上。

您可以创建Windows服务并将其安装到您的系统上。

因为您不能使用第三方库,或者将内部构件公开给另一个应用程序,这是公开通信端点(WCF、UDP、命名管道等)的选项吗?或者您可以监视另一个应用程序创建的“命令文件”文件夹?(使用FileSystemWatcher或简单计时器)


单独的应用程序可以将消息发送到此终结点/文件夹,Windows任务计划程序可以安排此应用程序。

由于您不能使用第三方库,也不能将内部构件公开给其他应用程序,因此是否可以公开通信终结点(WCF、UDP、命名管道等)?或者您可以监视另一个应用程序创建的“命令文件”文件夹?(使用FileSystemWatcher或简单计时器)

单独的应用程序可以将消息发送到此终结点/文件夹,Windows任务计划程序可以计划此应用程序。

正确的解决方案是使用Quartz.net或Windows任务计划程序,但既然您说您不能这样做,让我们想想您还可以做些什么

  • 您的程序需要一直运行。这意味着它应该是一个后台Windows服务应用程序。您不想让它成为一个用户应用程序,因为您不想与关闭应用程序的用户打交道,即使没有人登录,它也应该运行

  • 你不应该使用长定时器。相反,使用一个周期性运行的短计时器来检查是否到了执行事件的时间。短定时器应该多久运行一次?这是在空闲时要消耗多少资源和任务可以接受多少潜在延迟之间的折衷。如果需要运行wi
        //This code block is designed to schedule a timer for 5:35pm Eastern Time, regardless of whether is is Daylight Savings (EDT, UTC-4) or not (EST, UTC-5). 
        //  When understanding this code it is important to remember that a DateTime in UTC time represents an ABSOLUTE point in time. Any UTC time can only occur once. 
        //  A date time measured in local time (here we force Eastern Standard) is NOT ABSOLUTE. The same local time can occur twice (2am Nov 3nd 2013 for example)
        //Gets Eastern Timezone to be used in conversions
        TimeZoneInfo easternTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
        //Grabs the current time (UTC) 
        DateTime utcNowDateTime = DateTime.Now.ToUniversalTime();
        //Gets current time in Eastern Time (could be UTC-4 or -5 depending on time of year)
        DateTime easternNowDateTime = TimeZoneInfo.ConvertTime(utcNowDateTime, easternTimeZoneInfo);
        //Gets todays date
        DateTime easternNowDate = easternNowDateTime.Date;
        //Gets 5:35pm today or tomorrow depending on whether we are past 5:35pm or not. 
        //  Even though there are actually 18 hours from midnight to 5:35pm on Nov 2 2014 and 16 hours from midnight to 5:35pm on March 9 2014, 
        //  this will still end up at 5:35pm on those days because DateTime DOESNOT take into account the movement of the clocks (foreward or backward) when calling 
        //  .AddHours(), etc
        DateTime easternExpiryDateTime = easternNowDate.AddHours(17).AddMinutes(35).AddDays(easternNowDateTime.Hour >= 18 || (easternNowDateTime.Hour == 17 && easternNowDateTime.Minute >= 35) ? 1 : 0);
        //Convert the Easter Time date time to UTC. When subtracting this time from another UTC DateTime you will get the correct TimeSpan for use with a timer
        //  (even on 23 such as March 10th and 25 hour days such as November 3rd 2013)
        DateTime utcExpiryDateTime = easternExpiryDateTime.ToUniversalTime();
        //Set the timer to trigger at the desired point in the future.
        Timer timer = new Timer(
           ...,
           null,
           utcExpiryDateTime - utcNowDateTime ,
           ...);