有没有命令可以立即更新用户界面?

3
我希望您能使用以下代码更新进度条,从1到100递增:
```html

我想使用这段代码在进度条中更新从1到100的进度。

```
for (int i = 0; i <= 100; i++) {
    System.Threading.Thread.Sleep(100);
    progressBar1.Value = i;
}

但结果是,UI会在循环完成前冻结。

我知道Dispatcher可以帮助解决问题,但我不想拆分函数。

是否有任何命令可以立即更新UI,例如..

for (int i = 0; i <= 100; i++) {
    System.Threading.Thread.Sleep(100);
    progressBar1.Value = i;
    UpdateUINow();
}

编辑:我正在使用WPF,并使用Thread.Sleep来模拟长时间运行的过程。

实际上,我想要类似于Application.DoEvents的任何命令。 但我在WPF中找不到这个命令。

5个回答

15

不要在UI线程中睡眠,这会冻结您的UI - 这样做是不好的。

可以使用定时器(使用正确的类型的定时器,您应该能够使它在UI线程中触发),或者使用单独的线程(通过BackgroundWorker、一个新的独立线程或者ThreadPool)并让它回调到UI线程来更新它。

Application.DoEvents 是WinForms中一个hacky的解决方法,但是你提到了Dispatcher,这表明你正在使用WPF - 是这种情况吗?如果想使用这种解决方案,应该使用的定时器类型将取决于您正在使用的UI框架。


在WinForms中,Invoke(delegateInstance)可以完成工作。 - Mehrdad Afshari
2
+1 很高兴有人能够在我吃鸡肉条的时候反驳不断增长的“DoEvents”建议清单。 - Adam Robinson

2
另一种选择是使用BackgroundWorker(线程池可能有点过度kill,但从技术上讲也可以使用),并让它报告进度。

2
我会使用 C# 的 BackgroundWorker 来更新您的用户界面。这并不像您期望的那样工作,因为 Thread.Sleep() 会冻结您的 UI 线程。
编辑:这里有一个更符合您要求的教程 here

1

在主(GUI)线程中睡眠也是要尽量避免的。虽然你不想使用 Dispatcher,但我仍然建议尝试(类似于)这样做:

public partial class Window1 : Window
{
    DispatcherTimer _timer = new DispatcherTimer();

    public Window1()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        progressBar1.Value = 0;
        progressBar1.Maximum = 100;
        _timer.Interval = TimeSpan.FromMilliseconds( 100);
        _timer.Tick += ProgressUpdateThread;
        _timer.Start();
    }

    private void ProgressUpdateThread( object sender, EventArgs e)
    {
        progressBar1.Value++;
    }
}

-2

看看 DoEvents 是否能在这里帮助你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接