c# - 标签不会实时变化

标签 c# winforms

我有一个改变 label8 的循环。我希望我的 label8 实时更改,但我只得到最后一个值。我怎么做?我需要并行线程吗?

这是更改标签的代码:

private void Form1_Shown(object sender, EventArgs e)
{
    decimal C = 35;
    label8.Text = ":";

    while (true)
    {
        C -= Convert.ToDecimal(0.01);
        label8.Text = Convert.ToString(C);
        System.Threading.Thread.Sleep(200);

    }
}

最佳答案

这是因为 WinForm UI 是通过使用更新 Controller 的消息循环实现的,并在称为“UI 线程” 的特殊线程上运行。

MessageLoop 负责调用您注册的所有事件回调。 Stephan Toub 有一篇很棒的帖子关于这个话题Await, and UI, and deadlocks! Oh my!

在您的例子中,事件消息循环调用了 Form1_Shown 并使用 UI 线程运行它。在运行过程中,您命令当前线程(即 UI 线程并负责更新)进入休眠状态。然后您继续执行更多工作,直到循环结束。
你从来没有真正释放 UI 线程来做你自己以外的其他工作。 (其中一些作品正在收到您要更新的 Label.Text 的通知)

让线程休眠在绝大多数情况下是糟糕的设计或缺乏理解。

您可能想要延迟,这实际上可以释放线程以进行其他事件,但您不知道该怎么做,所以您将其置于休眠状态。

你可能想要这样的东西

private async void Form1_Shown(object sender, EventArgs e) // Notice the 'async'
{
    decimal C = 35;

    label8.Text = ":";
    while (true)
    {
        C -= Convert.ToDecimal(0.01);
        label8.Text = Convert.ToString(C);
        await Task.Delay(200); // Notice the 'await'
    }
}

关于c# - 标签不会实时变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53132157/

相关文章:

c# - 没有 Exists 方法,所以我想使用 AsQueryable 进行防御性编程

c# - 表单不响应 KeyDown 事件

c# - WinForms 线程间修改

c# - 如何从Sqlite请求中获取一个字段值?

c# - 自定义绑定(bind) .net 表单

vb.net - 为什么我的标签不显示在 VB.NET 表单中

c# - 在创建时调用 Lambda

c# - 在 EF 4.1 中使用 LINQ 进行涉及多对多关系比较的最有效方法是什么?

c# - 在 Windows 桌面应用程序中使用基于 Web 的 API

c# - 泛型方法多重 (OR) 类型约束