1

我正在尝试使用简单的例程,当我传入For更改标签值时。我睡了一秒钟,但什么也没发生

为什么这不起作用?我正在调试并看到标签的值传递,但屏幕没有变化。

代码

Random rand = new Random();
int randomNumber = 0;

for(int i = 0 ; i < 4; i++)
{
    randomNumber = rand.Next(1, 10);
    System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
    lblNumber.Text = Convert.ToString(randomNumber);
}

lblNumber.Text = Convert.ToString(randomNumber);
4

5 回答 5

6

但不会改变屏幕。

您正在阻止用户界面线程。标签只会在方法完成后更新一次,用户界面可以正常处理消息。

如果您想查看更新,则需要将此“工作”移至后台线程,并编组调用以将文本框设置回 UI 线程。

于 2013-03-15T20:10:57.397 回答
2

在 UI 线程上执行 Thread.Sleep 不会导致它更新显示(让它进入睡眠状态只会导致它在处理器上放弃它的时间大约 1 秒)。

如果你真的想触发更新,你可以考虑调用:Application.DoEvents()代替 Thread.Sleep。这将导致 UI 线程处理待处理的消息(其中将包括由于标签文本的更改而导致的一些重绘消息),这将反过来重绘控件。

但是您应该知道,这两种方法都被认为是不好的做法,并且表明您的代码存在一些问题。

于 2013-03-15T20:12:02.180 回答
1

设置标签的文本会告诉程序“下次您更新此表单的外观时,重新绘制标签”。但是由于您将要进行绘图的线程置于睡眠状态,因此在唤醒之前不会重绘标签。

睡眠不是你想在这里做的;如果您在 UI 线程上调用 Sleep,那么您几乎可以肯定做错了什么。

如果您使用的是 C# 5,则可以通过标记您的方法async然后使用来解决此问题

await Task.Delay(whatever);

而不是Thread.Sleep. “await”的意思是“去异步做某事,但不要进入睡眠等待结果。相反,将控制权返回给调用者。当异步操作完成时,将向 UI 线程发送一条消息,表示要恢复这种方法你离开的地方”。

为了使用await,您正在等待的方法必须返回voidorTaskTask<T>

于 2013-03-15T20:49:48.890 回答
0

你可以试着打电话

randomNumber = rand.Next(1, 10);
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
lblNumber.Text = Convert.ToString(randomNumber);
lblNumber.Refresh();
于 2013-03-15T20:12:50.853 回答
-1

这是因为您的 UI 更新在另一个线程中运行。除非您使用不同的线程,否则您不会看到标签更改。您可以使用BackgroundWorker来完成此操作。

于 2013-03-15T20:12:34.363 回答