有没有办法在Windows窗体中延迟事件处理程序(比如1秒)

13 .net c# events winforms

我需要能够延迟事件处理程序的某些控件(如按钮)被触发,例如在实际事件1秒后(例如单击事件)..这可能是.net框架吗?

我使用计时器并从计时器的tick事件中调用我的代码,如下所示,但我不确定这是否是最好的方法!

void onButtonClick( ..)
{
   timer1.Enabled = true;
}

void onTimerTick( ..)
{
   timer.Enabled = false; 

   CallMyCodeNow();
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*ngt 15

也许你可以创建一个创建计时器的方法?

void onButtonClick(object sender, EventArgs e)
{
    Delay(1000, (o,a) => MessageBox.Show("Test"));
}

static void Delay(int ms, EventHandler action)
{
    var tmp = new Timer {Interval = ms};
    tmp.Tick += new EventHandler((o, e) => tmp.Enabled = false);
    tmp.Tick += action;
    tmp.Enabled = true;
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 5

在回答你的问题之前,只需阅读主要问题页面中的摘要位,计时器就是我要提出的建议.

这看起来很干净.这意味着,如果需要,您可以通过再次禁用计时器轻松"取消"延迟事件.它还可以在UI线程中完成所有操作(但不会重入),这使得生活比其他替代方案更简单.


Rob*_*ney 5

如果您只为一个控件执行此操作,则计时器方法将正常工作.支持多个控件和事件类型的更强大的方法看起来像这样:

class Event
{
   public DateTime StartTime { get; set; }
   public Action Method { get; set; }

   public Event(Action method)
   {
      Method = method;
      StartTime = DateTime.Now + TimeSpan.FromSeconds(1);
   }
}
Run Code Online (Sandbox Code Playgroud)

Queue<Event>在表单中维护一个并且需要延迟的UI事件将它们添加到队列中,例如:

void onButtonClick( ..)
{
   EventQueue.Enqueue(new Event(MethodToCall));
}
Run Code Online (Sandbox Code Playgroud)

让你的计时器每秒钟滴答10次,并使其Tick事件处理程序如下所示:

void onTimerTick()
{
   if (EventQueue.Any() && EventQueue.First().StartTime >= DateTime.Now)
   {
      Event e = EventQueue.Dequeue();
      e.Method;
   }
}
Run Code Online (Sandbox Code Playgroud)


Bor*_*itz 5

我的解决方案使用 System.Threading.Timer:

public static class ExecuteWithDelay
{
    class TimerState
    {
        public Timer Timer;
    }

    public static Timer Do(Action action, int dueTime)
    {
        var state = new TimerState();
        state.Timer = new Timer(o =>
        {
            action();
            lock (o) // The locking should prevent the timer callback from trying to free the timer prior to the Timer field having been set.
            {
                ((TimerState)o).Timer.Dispose();
            }
        }, state, dueTime, -1);
        return state.Timer;
    }
}
Run Code Online (Sandbox Code Playgroud)