创建具有长延迟的任务是否可以接受?

时间:2016-07-07 18:42:52

标签: c# async-await task-parallel-library

我正在创建一个调度程序来在一天中的特定时间触发事件,为此我将使用Task.Delay旋转任务(一次一个,即“下一个”计划)延迟了几天。例如,在最后一个事件在星期五下午触发后,我将设置下一个星期一的某个时间,因此它可能是一个长达3天的TimeSpan(~260,000,000毫秒)。

这是可接受的做法吗?我担心这对于生产环境来说不够稳定/健壮。

这里有一些代码片段来描述我的内容:

private void SetNextEvent()
{
    TimeModel next = GetNextScheduledTime();
    Debug.WriteLine($"Next schedule [{next.TimeType}]: {next.Time.ToString("yyyy-MM-dd HH:mm:ss")}");

    TimeSpan delay = next.Time.Subtract(DateTime.Now);
    Task.Run(async () =>
    {
        await Task.Delay(delay);
        FireEvent(next);
    });
}

private void FireEvent(TimeModel time)
{
    Debug.WriteLine($"Event fired [{time.TimeType}]: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
    OnSchedulerEvent?.Invoke(this, new SchedulerEventArgs { ScheduleType = time.TimeType });
    if (_running)
        SetNextEvent();
}

3 个答案:

答案 0 :(得分:3)

这完全可靠。 .NET计时器非常有效。最大的问题是您必须假设您的生产应用程序可以随时退出。最容易理解的原因是杀死进程的错误。其他原因包括重新启动,应用程序池回收,部署,......

所以,如果你能在被杀之后恢复你的状态,这很好。如果您添加有关特定问题的评论,我会解决它们。

看起来你有办法恢复计时器,因为你显然可以计算下一个到期时间。在这种情况下,这样做是非常安全的。您需要确保代码始终在运行,例如在重启或崩溃之后。

注意,IIS应用程序需要容忍同时运行多次。否则,IIS是您的方案的绝佳主机。

答案 1 :(得分:0)

如果您正在运行Windows,我会使用TaskScheduler执行您尝试执行的操作。

运行taskschd.msc您可以使用该程序安排定期任务。

应该有一个"创建任务......"右侧面板中的按钮。

答案 2 :(得分:0)

我同意Windows任务计划程序可能是最好的方法,因为您事先知道运行下一个任务的计划。

如果您不提前知道(即等待下一个任务的时间可能会有所不同),那么我会建议在计时器到期时使用计时器和事件处理程序方法。

每次都可以设置计时器的Interval属性等待的时间。当时间到期时,定时器事件处理程序将运行,它可以执行询问并重置定时器的间隔。这似乎比Task.Delay更清洁。