在上次更改后更改控件的文本之前等待

Wait before changing a Control's text after previous change

我希望标签的文本在按下按钮后随其颜色一起改变。
第一部分是为了将 TextForeColor 更改为 Color.Orange,然后等待 1 秒,然后再次更改 Text 属性 并设置 ForeColorColor.LightGreen.

我的问题是它没有按照那个顺序执行,它只是跳过第一部分并转到第二部分(文本变为“完成!”并且颜色变为浅绿色)。

这是我的代码:

private void button1_Click(object sender, EventArgs e)
{
    label6.Text = "Working..";
    label6.ForeColor = Color.Orange;

    System.Threading.Thread.Sleep(1000);
    label6.Text = "Finsihed!";
    label6.ForeColor = Color.LightGreen;
}

你需要告诉你的标签在你睡觉之前更新

private void button1_Click(object sender, EventArgs e)
{
    label6.Text = "Working..";
    label6.ForeColor = Color.Orange;
    label6.Update(); // tell the label to update now

    System.Threading.Thread.Sleep(1000);
    label6.Text = "Finished!";
    label6.ForeColor = Color.LightGreen;
    label6.Update(); // tell the label to update now
}

但是还有另一种方法可以做到这一点。当您使用 async 并在您的点击方法中使用 Task.Delay() 而不是 Thread.Sleep() 时,无需调用 Update() 语句。
这也使您的表单保持响应。

这里有一个示例,说明如何在您的情况下执行此操作。

private async void button1_Click(object sender, EventArgs e)
{
    label6.Text = "Working..";
    label6.ForeColor = Color.Orange;

    await System.Threading.Tasks.Task.Delay(1000);
    label6.Text = "Finished!";
    label6.ForeColor = Color.LightGreen;
}

那么,Update()async 哪个更好?
好吧,这取决于

当您将 UpdateThread.Sleep() 一起使用时,您的表单将根据需要进行更新。但在您的 Thread.Sleep() 完成之前它也不会响应任何内容。
这可能是一件坏事,但也可能是一件好事。
这取决于你的情况。也许您不希望用户在 Thread.Sleep() 完成之前根本无法执行任何操作。但这也意味着用户不能将表单拖到其他位置。这可能会让用户感到厌烦。

当您使用 asyncTask.Delay() 时,您的表单也会根据需要更新。但它也会响应其他操作,如拖动、调整大小、点击等...
如果你想要这个,那么这就是你要走的路。
如果你不想要这个,那么要么再次使用 Update(),要么确保用户不能点击他不应该点击的任何东西。
后者是一个很好的解决方案,因为用户仍然可以将表单拖动到他想要的地方,为什么操作是 运行,但仍然不能做错任何事。
这意味着在您开始操作之前,禁用所有他不应该能够点击的控件,然后开始操作,当它完成时再次启用所有这些控件。
同意,这是更多的工作,但对用户来说看起来更好。

所以我认为使用 asyncTask.Delay() 是更好的解决方案。

由于您处于应用程序的主线程中,因此当您处于睡眠部分时不会对屏幕进行任何更新(您已将整个程序置于睡眠状态) 要显示更改,请执行 Application.DoEvents(); 在睡眠之前 - 这允许屏幕更新发生