【问题标题】:How to make timer with timeout如何制作带超时的计时器
【发布时间】:2011-08-11 00:41:54
【问题描述】:

我有一个缓慢的方法,在计时器(System.Timers.Timer)上执行它。有时它的执行时间比定时器的超时时间长,这会导致定时器等待。我希望将计时器设置为 30 毫秒,例如,在 30 毫秒后,重置方法,而不是等待。我应该使用哪种计时器?

编辑:

void OnTimerElapsed() {
      SomeMethod(args1);
      SomeMethod(args2);
      SomeMethod(args3);
}

SomeMethod 位于另一个程序集中。这是一种从另一个应用程序请求数据的同步方法。我不知道为什么它有时会挂起。这会导致计时器暂停,直到 SomeMethod() 继续。

【问题讨论】:

  • “重置方法”应该是什么意思?你确定不是在谈论 Thread.Abort?
  • 是的,我想在定时器超时后中止操作。
  • FWIW 中止线程被认为是非常糟糕的做法,因为您不知道如何从可能的错误状态中恢复、处理资源等。
  • 没有人会建议您放弃该方法。您必须告诉很多关于该方法的信息,以帮助我们帮助您找到一种很好地阻止它的方法。需要一个代码 sn-p 来显示它在做什么以及为什么需要这么长时间。

标签: .net timer c#-2.0


【解决方案1】:

使用System.Timers.Timer 并将其AutoReset 设置为false,并且仅在之前的时间结束或在您的自定义条件下启动它。这是我使用的模式:

private System.Timers.Timer _timer = new System.Timers.Timer();
private volatile bool _requestStop = false;

private void InitializeTimer()
{
    _timer.Interval = 100;
    _timer.Elapced += OnTimerElapced;
    _timer.AutoReset = false;
    _timer.Start();
}

private void OnTimerElapced(object sender, System.Timers.TimerEventArgs e)
{
    //_timer.Stop();//if AutoReset was not false

    //do work....

    if (!_requestStop)
    {
        _timer.Start();//restart the timer
    }
}

private void Stop()
{
    _requestStop = true;
    _timer.Stop();
}

private void Start()
{
    _requestStop = false;
    _timer.Start();
}

编辑:如果您想观看计时器并且如果操作需要更长的时间,那么您首先不应该使用计时器,而是使用将您的操作包装在新建一个线程并使用MaunalResetEvent,使用其WaitOne方法指定超时时间,如果发生超时则停止或左右操作。

【讨论】:

  • 使用 System.Timers.Timer 会使 OP 的问题变得更糟,他将有多个线程执行 OnTimerElapsed。非常非常糟糕。
  • 好的,但是如果“do work”需要很长时间才能完成,它也会挂起,直到它检查 requestStop
  • @blez 我编辑了答案以指定替代解决方案。
  • @Hans:我不明白他想中止线程的问题,当我看到他对你说他想中止操作的评论时,我编辑了答案..
猜你喜欢
  • 2018-08-05
  • 1970-01-01
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多