休眠和休眠之后,System.Timers.Timer在WPF应用程序中的行为如何? [英] How System.Timers.Timer behave in WPF application, after Hibernate, and Sleep?

查看:54
本文介绍了休眠和休眠之后,System.Timers.Timer在WPF应用程序中的行为如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在WPF应用程序中使用 System.Timers.Timer .我想了解计算机休眠后,Timer的行为方式,并使其进入睡眠状态.在计算机从休眠状态恢复后,我的应用程序出现了一些奇怪的问题.

我应该如何处理计时器?当计算机处于休眠/睡眠模式时,它们的行为如何?

我有一个午夜计时器,该计时器应在每个午夜工作以重置UI上的默认值.

以下是创建计时器的代码:

  private void ResetMidnightTimer(){//杀死旧计时器DisposeMidnightTimer();_midnightTimer =新的Timer();//安排计时器在午夜1分钟后过去_midnightTimer.Interval =(DateTime.Today.AddDays(1).AddMinutes(1)-DateTime.Now).TotalMilliseconds;_midnightTimer.Elapsed + =(_,__)=>UpdateRecommendedCollectingTime();_midnightTimer.Enabled = true;_midnightTimer.Start();} 

在UI页面的构造器上,我调用了调用ResestMidnightTimer()并实际创建计时器的方法.此后,计时器仅等待夜晚.

当晚上的时间(实际上是12:01 AM)到来时,计时器开始工作,按预期重置默认值,然后处置现有的计时器.最后,它将为第二天创建一个新的午夜计时器.但是,如果我尝试在当天使计算机休眠,则午夜计时器将不起作用,也不会重置默认值.

是因为在休眠状态时,事件处理只是延迟了与休眠状态相同的时间?

解决方案

这取决于您使用计时器的方式.如果您使用它们来启动一些不经常发生的事件(大于几分钟),那么您可能会看到一些怪异"的行为.由于您未指定怪异"行为是什么,因此我将假设您的程序计时器比预期时间晚了.

说明:进入睡眠/休眠状态的问题是所有程序均已暂停.这意味着您的计时器不会被更新,因此,当您进入睡眠/休眠状态并返回时,就好像您在睡眠/休眠状态的这段时间里被冻结一样.这意味着,如果您将计时器设置为在一个小时内关闭,并且您的计算机在15分钟标记后进入睡眠状态,则无论计算机睡眠了多长时间,一旦唤醒,它将还有另外45分钟的时间去运行.>

解决方案::一种解决方法是将DateTime保留在事件最后一次发生的时间附近.然后,使计时器定期关闭(每10秒或10分钟,取决于所需的精度),并检查最后一次执行的DateTime.如果现在与上一次执行时间之间的差大于或等于所需的时间间隔,则可以运行执行.

这将对其进行修复,以便在睡眠/休眠期间发生本来应该发生"的事件,该事件将从您从睡眠/休眠返回的那一刻开始.

更新:上面介绍的解决方案将起作用,我将填写一些详细信息以帮助您实现它.

  • 创建一个计时器以使用 RECURRING (将AutoReset属性设置为true),而不是创建/处置新的计时器

  • 应根据事件下次发生的时间设置单个计时器的间隔.相反,应将其设置为您选择的代表轮询频率的值(检查事件"是否应运行的频率).选择应该是效率和精度之间的平衡.如果需要它在真正接近上午12:01的时间运行,则将时间间隔设置为5-10秒左右.如果不太重要的是将其精确设置为上午12:01,则​​可以将间隔增加到大约1-10分钟.

  • 您需要保持上次执行发生的日期时间 OR 或下一次执行应该发生的时间.我希望何时应该执行下一次执行",这样您就不必每次经过计时器时都执行(LastExecutionTime + EventInterval),而只是比较当前时间和事件应发生的时间.

  • 一旦计时器过去并且发生 SHOULD 事件(大约在12:01 AM左右),则应更新存储的DateTime,然后在12:01 AM运行要运行的代码.

睡眠vs.休眠说明:睡眠和休眠之间的主要区别在于,在睡眠中,所有内容都保存在RAM中,而休眠将当前状态保存到磁盘中.休眠的主要优点是RAM不再需要电源,因此消耗的能量更少.这就是为什么在处理笔记本电脑或其他使用有限能量的设备时,建议在休眠状态下使用休眠模式的原因.

也就是说,程序的执行没有区别,因为在两种情况下它们都被挂起.不幸的是,System.Timers.Timer不会唤醒"计算机,因此您无法强制代码在〜12:01 AM运行.

我相信还有其他唤醒"计算机的方法,但是除非您采取最佳做法,否则您最好的方法是在定时器退出睡眠状态后的下一个轮询事件"期间运行事件"/休眠.

I'm using System.Timers.Timer in my WPF application. I want to understand how Timer does behave, after Computer is hibernated, and sleep. I'm getting some weird issues with my application, after computer is getting resumed from hibernate.

How should I handle timers, and how do they behave when computer is in hibernate/sleep mode?

I have a midnight timer which should work each midnight to reset the default values on UI.

Here is the code that creates the timer:

private void ResetMidnightTimer() 
        { 
            // kill the old timer
            DisposeMidnightTimer();

            _midnightTimer = new Timer();
            // scheduling the timer to elapse 1 minute after midnight
            _midnightTimer.Interval = (DateTime.Today.AddDays(1).AddMinutes(1) - DateTime.Now).TotalMilliseconds;
            _midnightTimer.Elapsed += (_, __) => UpdateRecommendedCollectingTime();
            _midnightTimer.Enabled = true;
            _midnightTimer.Start();
        }

On UI page's contructor, I call the method which calls ResestMidnightTimer() and creates the timer de facto. After that the timer just waits for the night.

When the night time (actually it is the 12:01 AM) comes, the timer works, resets the default values as expected and then disposes existing timer. Finally it creates a new midnight timer for next day. But if I try to hibernate the computer during that day, the midnight timer won't work and won't reset the default values.

Is that because while hibernating it just postpones the event handling by the same amount of time it was hibernated?

解决方案

This depends on how you are using your timers. If you are using them to initiate some event that occurs infrequently (greater than a couple minutes) then you will probably see some 'weird' behavior. Since you don't specify what that 'weird' behavior is, I'm going to assume that your program's timer goes off later than it should.

Explanation: The problem with going to sleep/hibernating is that all programs are suspended. This means that your Timers are not being updated and thus when you sleep/hibernate and come back, it is as if you were frozen for that period of time that you were sleeping/hibernating. This means if you have a timer set to go off in an hour and your computer goes to sleep at the 15 minute mark, once it wakes up it will have another 45 minutes to go, regardless of how long the computer was sleeping.

Solution: One fix would be to keep a DateTime around of the last time the event occurred. Then, have a timer go off periodically (every 10 seconds or 10 minutes, depending on the precision desired) and check the DateTime of the last execution. If the difference between now and the last execution time is greater than or equal to the interval desired, THEN you run execution.

This will fix it so that if an event 'should have' occurred during sleeping/hibernating, it will start the moment you return from sleeping/hibernating.

Update: The solution presented above will work and I'll fill in a couple of details to help you implement it.

  • Instead of creating/disposing of new Timers, create ONE timer to use that is RECURRING (the AutoReset property is set to true)

  • The interval of the single timer should NOT be set according to the next time the event should occur. Instead, it should be set to a value you choose that will represent the polling frequency (how often it checks to see if the 'event' should run). The choice should be a balance of efficiency and precision. If you NEED it to run REALLY close to 12:01 AM then you set the interval to around 5-10 seconds. If it is less important that it be at exactly 12:01 AM, you can increase the interval to something like 1-10 minutes.

  • You need to keep around a DateTime of when the last execution occurred OR when the next execution should happen. I would prefer 'when the next execution should happen' so that you aren't doing (LastExecutionTime + EventInterval) each time the timer elapses, you'll just be comparing the current time and the time the event should occur.

  • Once the timer elapses and the event SHOULD occur (somewhere around 12:01 AM), you should update the stored DateTime and then run the code you want run at 12:01 AM.

Sleep vs. Hibernate Clarification: The main difference between sleep and hibernate is that in sleep, everything is kept in RAM whereas hibernate saves the current state to disk. The main advantage of hibernate is that the RAM no longer needs power and thus expends less energy. This is why it is recommended to use hibernate over sleep when dealing with laptops or other devices using a finite amount of energy.

That said, there is no difference in the execution of programs as they are being suspended in either case. Unfortunately, the System.Timers.Timer does not 'wake up' a computer and so you can't enforce your code to be run at ~12:01 AM.

I believe there are OTHER ways to 'wake up' a computer but unless you go that route the best you can do is run your 'event' during the next 'polling event' of your timer after it comes out of sleep/hibernate.

这篇关于休眠和休眠之后,System.Timers.Timer在WPF应用程序中的行为如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆