【问题标题】:Get the value of a System.Windows.Forms.Timer?获取 System.Windows.Forms.Timer 的值?
【发布时间】:2013-03-20 20:26:06
【问题描述】:

windows 窗体计时器有点问题。这是一个非常基本的问题,但我环顾四周,似乎找不到答案(我可能值得一记耳光)。

我需要能够获取定时器的值,它的经过时间是否大于500ms的间隔。

类似

Timer.Elapsed >= 500

【问题讨论】:

  • 不可能。你想达到什么目的?也许Stopwatch 是你真正想要的?
  • 我试图在 500 毫秒后调用一个函数。
  • 那你要监听Elapsed事件。 Timer.Elapsed += tab tab done :)
  • 如果你想在 500 毫秒后调用一个函数,那么计时器听起来是个不错的解决方案。为什么不使用它?

标签: c# windows forms timer


【解决方案1】:

Timer.Elapsed 不是返回“已用时间”的属性 - 它是您订阅的 事件。这个想法是该事件每隔一段时间就会触发一次。

不清楚你是否想要Timer - 也许System.Diagnostics.Stopwatch 真的是你想要的?

var stopwatch = Stopwatch.StartNew();
// Do some work here

if (stopwatch.ElapsedMilliseconds >= 500)
{
    ...
}

【讨论】:

  • 荒谬的是,他们没有放一些东西来跟踪计时器的时间,而是创建了一个全新的类来做同样的事情。哈哈,微软总是把简单的事情复杂化。
  • @Liquid:不是真的。他们分离了两个独立的功能位:调度回调和测量经过的时间。你经常想要一个没有另一个。
【解决方案2】:

我需要能够获取计时器的值,它的经过时间是否大于500ms的间隔。

计时器不提供让您确定已经过去了多少时间的界面。他们唯一做的就是在过期时触发一个事件。

您需要使用其他机制记录时间流逝,例如Stopwatch 类。

【讨论】:

  • 每次启动计时器时存储DateTime.Now,然后在需要该值时进行数学运算不是更好吗?
  • @Andrew 为什么比Stopwatch好?
  • 鉴于无论如何您都需要一个辅助变量,我觉得存储struct 比实例化整个类要好。我也有感觉 Stopwatch 在运行时做某事,尽管在​​检查源代码后我发现它与DateTime 方法基本相同.
  • @Andrew 我看不出你所说的有什么好处
  • 在我的情况下,我尝试了这两种方法,但我没有发现太大的区别。此外,我需要显示剩余时间,直到下一次计时器击中,对于该数学,Stopwatch 也没有多大帮助。我称之为平局。
【解决方案3】:

将 Timer 的 Interval 属性设置为您想要触发的毫秒数(在您的示例中为 500),并为 Tick 事件添加事件处理程序。

【讨论】:

  • @Nathan 虽然这可能是解决您的问题的最佳方法,但它与您提出的问题无关。再次阅读您的问题,尤其是第二段。
  • @DavidHeffernan 如果 OP 提出 XY Problem 问题,我认为您应该回答 Y 而不是 X,而且我认为 called2voyage 在回答 Y 方面做得很好。
  • 真的很抱歉我应该问这个问题。
  • 我同意最初的问题措辞不当。也许将来,内森,您可以在原始问题中解决您实际尝试实现的目标(例如,当一段时间过去后,我如何执行某些代码?)然后在您的描述中解释您尝试过哪些方法(例如,我有寻找一种获取计时器经过时间的方法,但找不到任何方法。)。
  • @ScottChamberlain Er,使用元 XY Q 中接受的答案的符号,这个答案处理 X 而不是 Y。如果没有说明 X,就像这里的 Q 中的情况一样,那么它是很难指望人们会回答 X。至少有人应该说,“Y 的答案是……,但实际上你需要解决 X,你就是这样做的。”请记住,SO 是一个问答网站,我们首先要回答所提出的问题。
【解决方案4】:

Timer 无法做到这一点。 Elapsed是达到0时触发的事件。

如果您想在事件结束时收听,请注册收听ElapsedInterval是设置等待时间的成员。

请看这里: http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.100).aspx

【讨论】:

    【解决方案5】:

    我写得很快,可能有一些错误,但给你一个大致的想法

    Timer timer = new System.Windows.Forms.Timer();
    timer.Interval = 500;
    timer.Elapsed += (s,a) => {
      MyFunction();
      timer.Stop();
    }
    timer.Start();
    

    【讨论】:

      【解决方案6】:

      根据我与 David here 关于 StopwatchDateTime 的讨论,我决定针对需要获得剩余时间的情况发布这两种方法(非常简化),以便您决定哪种方法一个更适合你:

      public partial class FormWithStopwatch : Form
      {
          private readonly Stopwatch sw = new Stopwatch();
          // Auxiliary member to avoid doing TimeSpan.FromMilliseconds repeatedly
          private TimeSpan timerSpan;
      
          public void TimerStart()
          {
              timerSpan = TimeSpan.FromMilliseconds(timer.Interval);
              timer.Start();
              sw.Restart();
          }
      
          public TimeSpan GetRemaining()
          {
              return timerSpan - sw.Elapsed;
          }
      
          private void timer_Tick(object sender, EventArgs e)
          {
              // Do your thing
              sw.Restart();
          }
      }
      
      public partial class FormWithDateTime : Form
      {
          private DateTime timerEnd;
      
          public void TimerStart()
          {
              timerEnd = DateTime.Now.AddMilliseconds(timer.Interval);
              timer.Start();
          }
      
          public TimeSpan GetRemaining()
          {
              return timerEnd - DateTime.Now;
          }
      
          private void timer_Tick(object sender, EventArgs e)
          {
              // Do your thing
              timerEnd = DateTime.Now.AddMilliseconds(timer.Interval);
          }
      }
      

      老实说,我认为使用Stopwatch 并没有太大的好处。通过使用DateTime,您实际上需要更少的行。此外,后者对我来说似乎更清楚一点。

      【讨论】:

        【解决方案7】:

        我提出了一个很简单的解决方案:

        1 - 在启动计时器之前,我将当前时间存储在 TotalMillisseconds(来自 DateTime.Now.TimeOfDay.TotalMilliseconds):

        double _startingTime = DateTime.Now.TimeOfDay.TotalMilliseconds;
        

        2 - 每次计时器计时,我都会再次获取当前时间,然后我使用 double 变量来获取这两者之间的差异:

        double _currentTime = DateTime.Now.TimeOfDay.TotalMilliseconds;
        double _elapsed = _currentTime - _startingTime;
        
        if(_elapsed >= 500)
        {
            MessageBox.Show("As you command, master!");
            _startingTime = _currentTime;
        }
        
        if(_currentTime < _startingTime)
            _startingTime = _currentTime;
        

        3 - 最后,因为TotalMilliseconds 将返回自 00:00(下午 12 点)以来经过的毫秒数,这意味着当它是午夜时,TotalMilliseconds 将等于 0。在这种情况下我只是检查_currentTime是否低于_startingTime,如果是,则将_startingTime设置为_currentTime,以便我再次计算。

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-08-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-04
          相关资源
          最近更新 更多