c# – 如何使用定时器等待?

前端之家收集整理的这篇文章主要介绍了c# – 如何使用定时器等待?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试通过使用定时器来延迟我的方法中的事件,但是我不一定了解如何使用定时器等待.

我设置了我的定时器为2秒,但是当我运行这个代码时,最后一个调用没有延迟2秒.

Timer timer = new Timer();
timer.Tick += new EventHandler(timer_Tick); // Everytime timer ticks,timer_Tick will be called
timer.Interval = (1000) * (2);              // Timer will tick evert second
timer.Enabled = true;                       // Enable the timer


void timer_Tick(object sender,EventArgs e)
{
    timer.Stop();
}

private void button1_Click(object sender,EventArgs e)
{
    label1.Text = "first";
    timer.Start();
    label1.Text = "second";
}

所以当我点击我的按钮,它立即显示label1为“第二”,而不是改为“第一”,等待2秒,然后更改为“秒”.我已经阅读了很多线程关于使用timers而不是thread.sleep,但我似乎找不到/找出如何实际实现.

解决方法

timer.Start()刚刚启动定时器,但是在定时器在后台运行时立即返回.所以在将标签文本设置为第一个和第二个之间几乎没有暂停.你想要做的是等待定时器勾选,然后再次更新标签
void timer_Tick(object sender,EventArgs e)
{
    timer.Stop();
    label1.Text = "second";
}

private void button1_Click(object sender,EventArgs e)
{
    label1.Text = "first";
    timer.Start();
}

顺便说一句.您不应将timer.Enabled设置为true,您已经使用timer.Start()启动定时器.

如注释所述,您可以将计时器创建放在一个方法中,像这样(注意:这是未经测试的):

public void Delayed(int delay,Action action)
{
    Timer timer = new Timer();
    timer.Interval = delay;
    timer.Tick += (s,e) => {
        action();
        timer.Stop();
    };
    timer.Start();
}

然后你可以这样使用它:

private void button1_Click(object sender,EventArgs e)
{
    label1.Text = "first";
    Delayed(2000,() => label1.Text = "second");
}

Tergiver的后续行动

Does using Delayed contain a memory leak (reference leak)?

Subscribing to an event always creates a two-way reference.

In this case timer.Tick gets a reference to an anonymous function (lambda). That function lifts a local variable timer,though it’s a reference,not a value,and contains a reference to the passed in Action delegate. That delegate is going to contain a reference to label1,an instance member of the Form. So is there a circular reference from the Timer to the Form?

I don’t know the answer,I’m finding it a bit difficult to reason about. Because I don’t know,I would remove the use of the lambda in Delayed,making it a proper method and having it,in addition to stopping the timer (which is the sender parameter of the method),also remove the event.

通常,lambdas不会对垃圾收集造成问题.在这种情况下,定时器实例仅在本地存在,并且lambda中的引用不会阻止垃圾回收来收集实例(另见this question).

我实际上使用.NET内存分析器测试了这一点.定时器对象被收集得很好,没有发生泄漏.分析器确实给了我一个警告,有些情况下,“[…]已被垃圾收集,没有妥善处理”.删除事件处理程序本身(通过保留对它的引用)没有修复,虽然.将捕获的定时器引用更改为(定时器)也没有改变.

有什么帮助 – 显然是在停止定时器之后在事件处理程序中调用timer.Dispose(),但是我认为是否真的有必要.我不认为分析器警告/注释是至关重要的.

猜你在找的C#相关文章