如何使用计时器等待?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用计时器等待?相关的知识,希望对你有一定的参考价值。
我试图通过使用计时器延迟我的方法中的事件,但我不一定了解如何使用计时器等待。
我将我的计时器设置为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显示为“second”,而不是更改为“first”,等待2秒,然后更改为“second”。我在这里阅读了许多关于使用计时器而不是thread.sleep的线程,但我似乎无法找到/弄清楚如何实际实现它。
timer.Start()
只是启动计时器,但在计时器在后台运行时立即返回。因此,在将标签文本设置为first
和second
之间几乎没有停顿。你想要做的是等待定时器勾选,然后再次更新标签:
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的后续行动
使用Delayed是否包含内存泄漏(引用泄漏)?
订阅事件始终会创建双向引用。
在这种情况下,
timer.Tick
获取对匿名函数(lambda)的引用。该函数提升局部变量timer
,虽然它是一个引用,而不是一个值,并包含对传入的Action委托的引用。该代表将包含对label1
的引用,Form
是Timer
的实例成员。那么从Form
到Delayed
有一个循环引用吗?我不知道答案,我发现它有点难以推理。因为我不知道,我会删除
sender
中lambda的使用,使它成为一个合适的方法并拥有它,除了停止计时器(这是方法的this question参数),也删除事件。
通常lambdas不会导致垃圾收集问题。在这种情况下,计时器实例仅存在于本地,并且lambda中的引用不会阻止垃圾收集来收集实例(另请参阅(Timer)s
)。
我实际上使用.NET Memory Profiler再次测试了这个。收集的计时器对象很好,没有发生泄漏。该分析器确实给了我一个警告,即有些情况“虽然没有妥善处理,但已经收集了垃圾”。删除事件处理程序本身(通过保持对它的引用)并没有解决这个问题。将捕获的计时器引用更改为timer.Dispose()
也没有改变。
什么帮助 - 显然是 - 在停止计时器后在事件处理程序中调用await
,但我认为这是否真的有必要。我不认为分析器警告/注释是关键的。
如果您正在使用C#5.0,private async void button1_Click(object sender, EventArgs e)
{
label1.Text = "first";
await Task.Delay(2000);
label1.Text = "second";
}
可以让您更轻松:
label1.Text = "second";
如果你想要做的就是在计时器滴答时更改文本,那么你最好放下......
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();
}
...在计时器滴答中,在将计时器更改为enabled = false之前或之后;
像这样;
private bool Delay(int millisecond)
{
Stopwatch sw = new Stopwatch();
sw.Start();
bool flag = false;
while (!flag)
{
if (sw.ElapsedMilliseconds > millisecond)
{
flag = true;
}
}
sw.Stop();
return true;
}
bool del = Delay(1000);
qazxswpoi
以上是关于如何使用计时器等待?的主要内容,如果未能解决你的问题,请参考以下文章