当托管在 Azure 上时,警报被安排晚一个小时
Alert getting scheduled an hour late when hosted on Azure
我正在使用 hangfire 安排在用户指定的时间发送电子邮件警报。当我在本地主机上测试应用程序时,警报被安排在正确的时间,当我向 Azure 上托管的实时应用程序发送请求时,请求被安排在一个小时后。
我认为问题是我对 DateTimeOffset 缺乏了解。我在 JobScheduler class 中所做的是
public class JobScheduler : IJobScheduler
{
private EmailManager _emailManager;
public JobScheduler(IAlertManager alertManager)
{
_alertManager = alertManager;
}
public string ScheduleRaiseDateAlert( DateDetail date)
{
DateTimeOffset jobRunTime = ConvertToDateTimeOffSet(date.CheckInTime);
return BackgroundJob.Schedule(()=> _alertManager.RaiseAlertAsync(date.Id, true), jobRunTime.DateTime);
}
private DateTimeOffset ConvertToDateTimeOffSet(DateTime futureDateTime)
{
futureDateTime = DateTime.SpecifyKind(futureDateTime, DateTimeKind.Utc);
DateTimeOffset ScheduleTime = futureDateTime;
return ScheduleTime;
}
}
date.CheckInTime 是应该向用户发送电子邮件的日期时间
例如:如果 date.CheckInTime = 17/04/2018 19:02:00 当我发送请求时在本地主机上,作业将安排在该日期和时间,当我向 azure 上托管的应用程序发送相同的请求时,作业安排的时间是 17/04/2018 20:02:00
AFAIK,DateTimeOffset.DateTime
将被视为本地日期时间,您可以检查发送到 BackgroundJob.Schedule
的 jobRunTime.DateTime
实例的 Kind
属性 ].
对于支持 DateTimeOffset
参数的 BackgroundJob.Schedule
的方法重载,存储的 EnqueueAt 将是您的 DateTimeOffset
的 DateTimeOffset.UtcDateTime
=] 参数.
对于 TimeSpan
参数,存储的 EnqueueAt 将是当前 UTC 日期时间加上您指定的 TimeSpan。
此外,如果您将本地时间 DateTime
实例传递给 BackgroundJob.Schedule
,存储的 EnqueueAt 将被转换为相关的 UTC 日期时间。
由于您没有提供如何构建 DateDetail
,我建议您检查存储的任务以缩小此问题的范围。我使用了 UseSqlServerStorage,对于这种方法,您可以在 HangFire.State
table.
下查看计划任务的状态
{"EnqueueAt":"2018-04-20T06:39:28.0305044Z","ScheduledAt":"2018-04-18T06:39:29.5398973Z"}
ScheduledAt
代表你创建这个任务的UTC日期时间,EnqueueAt
代表任务触发的UTC日期时间。
我正在使用 hangfire 安排在用户指定的时间发送电子邮件警报。当我在本地主机上测试应用程序时,警报被安排在正确的时间,当我向 Azure 上托管的实时应用程序发送请求时,请求被安排在一个小时后。
我认为问题是我对 DateTimeOffset 缺乏了解。我在 JobScheduler class 中所做的是
public class JobScheduler : IJobScheduler
{
private EmailManager _emailManager;
public JobScheduler(IAlertManager alertManager)
{
_alertManager = alertManager;
}
public string ScheduleRaiseDateAlert( DateDetail date)
{
DateTimeOffset jobRunTime = ConvertToDateTimeOffSet(date.CheckInTime);
return BackgroundJob.Schedule(()=> _alertManager.RaiseAlertAsync(date.Id, true), jobRunTime.DateTime);
}
private DateTimeOffset ConvertToDateTimeOffSet(DateTime futureDateTime)
{
futureDateTime = DateTime.SpecifyKind(futureDateTime, DateTimeKind.Utc);
DateTimeOffset ScheduleTime = futureDateTime;
return ScheduleTime;
}
}
date.CheckInTime 是应该向用户发送电子邮件的日期时间
例如:如果 date.CheckInTime = 17/04/2018 19:02:00 当我发送请求时在本地主机上,作业将安排在该日期和时间,当我向 azure 上托管的应用程序发送相同的请求时,作业安排的时间是 17/04/2018 20:02:00
AFAIK,DateTimeOffset.DateTime
将被视为本地日期时间,您可以检查发送到 BackgroundJob.Schedule
的 jobRunTime.DateTime
实例的 Kind
属性 ].
对于支持 DateTimeOffset
参数的 BackgroundJob.Schedule
的方法重载,存储的 EnqueueAt 将是您的 DateTimeOffset
的 DateTimeOffset.UtcDateTime
=] 参数.
对于 TimeSpan
参数,存储的 EnqueueAt 将是当前 UTC 日期时间加上您指定的 TimeSpan。
此外,如果您将本地时间 DateTime
实例传递给 BackgroundJob.Schedule
,存储的 EnqueueAt 将被转换为相关的 UTC 日期时间。
由于您没有提供如何构建 DateDetail
,我建议您检查存储的任务以缩小此问题的范围。我使用了 UseSqlServerStorage,对于这种方法,您可以在 HangFire.State
table.
{"EnqueueAt":"2018-04-20T06:39:28.0305044Z","ScheduledAt":"2018-04-18T06:39:29.5398973Z"}
ScheduledAt
代表你创建这个任务的UTC日期时间,EnqueueAt
代表任务触发的UTC日期时间。