3

我想使用此代码将进度条从运行 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 中找不到这个命令。

4

5 回答 5

15

不要在 UI 线程中休眠。它会冻结你的用户界面——这是一件坏事。

要么有某种计时器(使用正确的计时器,你应该能够让它在你的 UI 线程中触发)或使用单独的线程(通过BackgroundWorker、新的单独线程或ThreadPool)并使其调用返回 UI 线程进行更新。

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

于 2009-11-19T17:27:36.447 回答
2

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

于 2009-11-19T17:28:24.803 回答
2

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

编辑:教程可以在这里做更多你想要的

于 2009-11-19T17:29:32.257 回答
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++;
    }
}
于 2009-11-20T03:49:04.477 回答
-2

看看DoEvents是否可以在这里为您提供帮助。

于 2009-11-19T17:26:24.623 回答