Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在执行任何函数之前,我如何跟踪时间?_C#_Asp.net Core - Fatal编程技术网

C# 在执行任何函数之前,我如何跟踪时间?

C# 在执行任何函数之前,我如何跟踪时间?,c#,asp.net-core,C#,Asp.net Core,我有一个每秒调用通知功能的服务。此函数的作用是检查lastupdated和DateTime.UtcNow之间的时间差,并检查Countdiff是否大于1 如果上述条件为真,那么它将检查AppGuid是否已经在数据库中,如果不是,则插入它并调用发送通知的DoAction函数。在这之前一切都很顺利 当AppGuid已经在DB中时,问题开始出现 我需要的是,如果AppGuid已经在数据库中,那么每15分钟发送一次通知,在这里我努力跟踪上次发送通知的时间,我尝试比较上次更新时的时间戳,并尝试比较差异,但

我有一个每秒调用通知功能的服务。此函数的作用是检查lastupdated和DateTime.UtcNow之间的时间差,并检查Countdiff是否大于1

如果上述条件为真,那么它将检查AppGuid是否已经在数据库中,如果不是,则插入它并调用发送通知的DoAction函数。在这之前一切都很顺利

当AppGuid已经在DB中时,问题开始出现

我需要的是,如果AppGuid已经在数据库中,那么每15分钟发送一次通知,在这里我努力跟踪上次发送通知的时间,我尝试比较上次更新时的时间戳,并尝试比较差异,但它不断发送通知,导致管道中出现垃圾邮件

我试图用秒表类保持弹性时间,但问题是当应用程序开始发送任何内容时,它会等待15分钟

如何每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分钟时,我会在中场休息时打上一圈。