C# 在执行任何函数之前,我如何跟踪时间?
我有一个每秒调用通知功能的服务。此函数的作用是检查lastupdated和DateTime.UtcNow之间的时间差,并检查Countdiff是否大于1 如果上述条件为真,那么它将检查AppGuid是否已经在数据库中,如果不是,则插入它并调用发送通知的DoAction函数。在这之前一切都很顺利 当AppGuid已经在DB中时,问题开始出现 我需要的是,如果AppGuid已经在数据库中,那么每15分钟发送一次通知,在这里我努力跟踪上次发送通知的时间,我尝试比较上次更新时的时间戳,并尝试比较差异,但它不断发送通知,导致管道中出现垃圾邮件 我试图用秒表类保持弹性时间,但问题是当应用程序开始发送任何内容时,它会等待15分钟 如何每15分钟只发送一次通知C# 在执行任何函数之前,我如何跟踪时间?,c#,asp.net-core,C#,Asp.net Core,我有一个每秒调用通知功能的服务。此函数的作用是检查lastupdated和DateTime.UtcNow之间的时间差,并检查Countdiff是否大于1 如果上述条件为真,那么它将检查AppGuid是否已经在数据库中,如果不是,则插入它并调用发送通知的DoAction函数。在这之前一切都很顺利 当AppGuid已经在DB中时,问题开始出现 我需要的是,如果AppGuid已经在数据库中,那么每15分钟发送一次通知,在这里我努力跟踪上次发送通知的时间,我尝试比较上次更新时的时间戳,并尝试比较差异,但
public class DataGetService : DelegatingHandler, IHostedService
{
private Timer _timer;
Stopwatch stopwatch = new Stopwatch();
public Task StartAsync(CancellationToken cancellationToken)
{
stopwatch.Start();
_timer = new Timer(Heartbeat, null, 1000, 1000);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
//Timer does not have a stop.
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Heartbeat(object state)
{
_ = Notifications(TimeSpan.FromMinutes(15));
}
public async Task Notifications(TimeSpan period)
{
// Result array have: LastUpdated, CountDiff, AppGuid, AppName, Timestamp
foreach (var d in result)
{
var x = _DBcontext.TestEvents.FirstOrDefault(o => o.AppGuid == (Guid)d.AppGuid);
if (DateTime.UtcNow - d.LastUpdated <= TimeSpan.FromMinutes(30) && d.CountDiff > 1)
{
if (x == null)
{
DoAction();
_DBcontext.TestEvents.Add(new TestEvents
{
AppGuid = (Guid)d.AppGuid,
AppName = d.AppName,
Timestamp = DateTime.UtcNow
});
}
else
{ //This is useful if app have crashed or was not able to update in db, it will update the current timestamp.
if (DateTime.UtcNow - x.Timestamp >= TimeSpan.FromMinutes(30))
{
x.Timestamp = DateTime.UtcNow;
}
else
{
if (stopwatch.Elapsed <= period)
return;
DoAction();
x.Timestamp = DateTime.UtcNow;
}
}
}
}
await _DBcontext.SaveChangesAsync();
stopwatch.Restart();
}
}
如果用户多次尝试密码,我会用同样的方法将其锁定15分钟:与其尝试使用日期字段来跟踪记录上次更新的时间,不如使用一个专用字段来记录下一个事件应该何时引发。在发送第一个通知时,请将其设置为未来日期,并且仅当该日期已过时才发送新通知,然后再次设置未来日期
通过使用上次更新的字段,如果记录的其他内容发生更改,则可能会再次收到通知。如果你觉得把日期放在相关表中并不重要,考虑一下有一个表来通知事件日期;它所需要的只是一个GUID和一个日期,然后如果GUID是唯一的,它就可以为数据库中任何表中的任何对象ID起作用-在这种情况下,在时间y是一件容易编码的事情之前,不发送关于GUID为x的实体的信息,并且事件系统不需要知道关于它报告的实体的任何信息。如果子系统愿意的话,您可以让它们每秒钟简单地引发一次事件,但是通知的发送只能每X分钟发生一次,因此所有临时通知都会被终止。这也简化了发送消息的系统;它只会引发他们,而不关心他们是否真的应该得到通知的逻辑我会这样做,如果用户尝试密码太多次,我会将用户锁定15分钟:而不是尝试使用跟踪记录上次更新时间的日期字段,为下一个事件的引发时间设置专用字段。在发送第一个通知时,请将其设置为未来日期,并且仅当该日期已过时才发送新通知,然后再次设置未来日期
通过使用上次更新的字段,如果记录的其他内容发生更改,则可能会再次收到通知。如果你觉得把日期放在相关表中并不重要,考虑一下有一个表来通知事件日期;它所需要的只是一个GUID和一个日期,然后如果GUID是唯一的,它就可以为数据库中任何表中的任何对象ID起作用-在这种情况下,在时间y是一件容易编码的事情之前,不发送关于GUID为x的实体的信息,并且事件系统不需要知道关于它报告的实体的任何信息。如果子系统愿意的话,您可以让它们每秒钟简单地引发一次事件,但是通知的发送只能每X分钟发生一次,因此所有临时通知都会被终止。这也简化了发送消息的系统;它只会提出他们,而不关心他们是否应该得到通知的逻辑 我添加了futureTime变量,它从DB向时间戳添加了15分钟 有趣的是,当我与ifDateTime.UtcNow==futureTime进行比较时,条件从未变为真,我所理解的原因是,在执行过程中,我每隔一秒调用这个函数,不知何故,系统跳过了导致假条件的时间 为了克服这个问题,我采用了差分数据方法。p>
if (DateTime.UtcNow - d.LastUpdated <= TimeSpan.FromMinutes(30) && d.CountDiff > 1)
{
if (x == null)
{
DoAction();
_DBcontext.TestEvents.Add(new TestEvents
{
AppGuid = (Guid)item.AppGuid,
AppName = item.AppName,
Timestamp = DateTime.UtcNow
});
}
//This is useful if app have crashed or was not able to update in db, it will update the current timestamp.
else if (DateTime.UtcNow - x.Timestamp >= TimeSpan.FromMinutes(30))
{
x.Timestamp = DateTime.UtcNow;
}
else
{
//This will set the notification date in future
DateTime dbtimestamp = x.Timestamp;
DateTime futureTime = dbtimestamp.AddMinutes(15);
if (((DateTime.UtcNow - futureTime) - TimeSpan.FromSeconds(1)).Duration() < TimeSpan.FromSeconds(1.0))
{
DoAction();
x.Timestamp = DateTime.UtcNow;
}
}
}
对于未来的寻求答案者: 我添加了futureTime变量,它从DB向时间戳添加了15分钟 有趣的是,当我与ifDateTime.UtcNow==futureTime进行比较时,条件从未变为真,我所理解的原因是,在执行过程中,我每隔一秒调用这个函数,不知何故,系统跳过了导致假条件的时间 为了克服这个问题,我采用了差分数据方法。p>
if (DateTime.UtcNow - d.LastUpdated <= TimeSpan.FromMinutes(30) && d.CountDiff > 1)
{
if (x == null)
{
DoAction();
_DBcontext.TestEvents.Add(new TestEvents
{
AppGuid = (Guid)item.AppGuid,
AppName = item.AppName,
Timestamp = DateTime.UtcNow
});
}
//This is useful if app have crashed or was not able to update in db, it will update the current timestamp.
else if (DateTime.UtcNow - x.Timestamp >= TimeSpan.FromMinutes(30))
{
x.Timestamp = DateTime.UtcNow;
}
else
{
//This will set the notification date in future
DateTime dbtimestamp = x.Timestamp;
DateTime futureTime = dbtimestamp.AddMinutes(15);
if (((DateTime.UtcNow - futureTime) - TimeSpan.FromSeconds(1)).Duration() < TimeSpan.FromSeconds(1.0))
{
DoAction();
x.Timestamp = DateTime.UtcNow;
}
}
}
啊,我明白了,没关系。我会用一个系统。计时器。计时器。。。。自动重置=错误。当我从1秒切换到15分钟的时候,我会在中场休息的时候玩。啊,我明白了,没关系,我会使用一个系统。计时器。计时器。。。。金 重置=错误。当我从1秒换到15分钟时,我会在中场休息时打上一圈。