是否有任何命令立即更新UI?

时间:2009-11-19 17:24:05

标签: c# wpf user-interface asynchronous dispatcher

我想使用此代码更新从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 个答案:

答案 0 :(得分:15)

不要在UI线程中睡觉。它会冻结你的UI - 这是一件坏事。

要么有某种计时器(使用正确的计时器,你应该能够在你的UI线程中启动它)或者使用一个单独的线程(通过BackgroundWorker,一个新的单独的线程,或ThreadPool)并让它回调到UI线程进行更新。

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

答案 1 :(得分:2)

另一种选择是使用BackgroundWorker(ThreadPool在这里有点过分但技术上可以使用)并让它报告进度。

答案 2 :(得分:2)

我会使用C#BackgroundWorker来更新您的用户界面。这不像你期望的那样,因为Thread.Sleep()冻结你的UI线程。

编辑:教程可以完成您想要的更多内容here

答案 3 :(得分: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++;
    }
}

答案 4 :(得分:-2)

查看DoEvents是否可以帮助您。