【问题标题】:C# wait timeout before calling method and reset timer on consecutive callsC#在调用方法之前等待超时并在连续调用时重置计时器
【发布时间】:2016-06-22 17:51:46
【问题描述】:

我的代码中有一个事件可能在某个时刻每秒被触发多次。

但是我想实现一种方法,使该方法在真正触发之前等待 500 毫秒,如果在 500 毫秒结束之前再次调用该方法,请重置计时器并再次等待 500 毫秒。

来自 javascript 我知道这可以通过 setTimeout 或 setInterval 实现。但是,我无法弄清楚如何在 C# 中实现这样的事情。

【问题讨论】:

    标签: c# timer timeout intervals


    【解决方案1】:

    您可以使用包装在一个类中的System.Timers.Timer 来获得您需要的行为:

    public class DelayedMethodCaller
    {
        int _delay;
        Timer _timer = new Timer();
    
        public DelayedMethodCaller(int delay)
        {
            _delay = delay;
        }
    
        public void CallMethod(Action action)
        {
            if (!_timer.Enabled)
            {
                _timer = new Timer(_delay)
                {
                    AutoReset = false
                };
                _timer.Elapsed += (object sender, ElapsedEventArgs e) =>
                    {
                        action();
                    };
                _timer.Start();
            }
            else
            {
                _timer.Stop();
                _timer.Start();
            }
        }
    }
    

    这可以通过以下方式使用:

    public class Program
    {
        static void HelloWorld(int i)
        {
            Console.WriteLine("Hello World! " + i);
        }
    
        public static void Main(string[] args)
        {
            DelayedMethodCaller methodCaller = new DelayedMethodCaller(500);
            methodCaller.CallMethod(() => HelloWorld(123));
            methodCaller.CallMethod(() => HelloWorld(123));
            while (true)
                ;
        }
    }
    

    如果您运行该示例,您会注意到“Hello World!123”只显示一次 - 第二次调用只是重置计时器。

    【讨论】:

      【解决方案2】:

      如果再次调用该方法时需要重置计时器,请考虑查看 ManualResetEvent 类:

      https://msdn.microsoft.com/en-us/library/system.threading.manualresetevent(v=vs.110).aspx

      您可以使用它来通知一个或多个等待线程发生了事件。

      【讨论】:

      • 有趣。会挖
      【解决方案3】:

      您可以使用 Thread.Sleep() 锁定

      private object locking = new object();
      
      lock (locking )
      {
          Thread.Sleep(500);
          //Your code to run here
      }
      

      https://msdn.microsoft.com/en-us/library/system.threading.thread.sleep(v=vs.110).aspx

      【讨论】:

      • 如果再次触发相同的方法,我如何阻止该线程执行?
      • 更新了答案。在睡眠中使用锁定。
      • 不确定我的问题是不是太含糊,还是我错过了什么。但这会阻止其他调用触发此代码对吗?如果再次调用该方法,我正在寻找的是将计时器重置为 0。 (所以忽略以前的电话)
      • 锁将阻止任何其他线程运行锁内的代码,直到锁被释放。因此,一旦锁被释放,另一个线程可以进入,该线程将再次休眠 500 毫秒。因此无需再次将“计时器”重置为 0。所以本质上调用是排队的,当你说重置计时器时,你的意思是线程被锁定以忽略它们时的任何调用?
      • 方便的东西,但不是我想要的。将更新我的问题。
      猜你喜欢
      • 2016-05-04
      • 2016-08-20
      • 2013-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 2015-12-22
      相关资源
      最近更新 更多