C# 在 wpf 中实时更新进度条

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29872663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 04:20:32  来源:igfitidea点击:

Making a progress bar update in real time in wpf

c#wpfwpf-controls

提问by nonion

I'm having some trouble making the progress bar show the updates in real time.

我在使进度条实时显示更新时遇到了一些麻烦。

This is my code right now

这是我现在的代码

for (int i = 0; i < 100; i++)
{
     progressbar1.Value = i;
     Thread.Sleep(100);
}

But for some reason the progress bar shows empty when the function runs, and then nothing until the function finishes running. Can someone explain to me how this can be done? I'm new to C#/WPF so I'm not 100% sure on how I would implement a Dispatcher on a different thread (as seen on some other posts) to fix this problem.

但是由于某种原因,当函数运行时进度条显示为空,然后在函数完成运行之前什么都没有。有人可以向我解释如何做到这一点吗?我是 C#/WPF 的新手,所以我不能 100% 确定如何在不同的线程上实现调度程序(如其他一些帖子所示)来解决这个问题。

To clarify, my program has a button which when press, grabs the value from a textbox, and uses an API to retrieve info, and create labels based on it. I want the progress bar to update after every row of data is finished processing.

澄清一下,我的程序有一个按钮,按下该按钮时,从文本框中获取值,并使用 API 检索信息,并基于它创建标签。我希望在处理完每一行数据后更新进度条。

This is what I have right now:

这就是我现在所拥有的:

private async void search(object sender, RoutedEventArgs e)
{
    var progress = new Progress<int>(value => progressbar1.Value = value);
    await Task.Run(() =>
    {
        this.Dispatcher.Invoke((Action)(() =>
        {
             some pre-processing before the actual for loop occur
             for (int i = 0; i < numberofRows; i++)
             {
                  label creation + adding
                  ((IProgress<int>)progress).Report(i);
             }
        }));
    });
}

Thank you!

谢谢!

采纳答案by nonion

Managed to make it work. All I needed to do is instead of making it just

设法使它工作。我需要做的就是而不是让它只是

progressBar1.value = i;

I just had to do

我只需要做

progressbar1.Dispatcher.Invoke(() => progressbar1.Value = i, DispatcherPriority.Background);

回答by Saagar Elias Hymany

You should use BackgroundWorkerincluded in .NET, which provides you with methods for reporting the progress of a background thread in an event. The thread which created the BackGroundWorker automatically calls this event.

您应该使用.NET 中包含的BackgroundWorker,它为您提供了报告事件中后台线程进度的方法。创建 BackGroundWorker 的线程会自动调用此事件。

The BackgroundWorker.ProgressChangedcan be used to report the progress of an asynchronous operation to the user.

BackgroundWorker.ProgressChanged可以被用来报告一个异步操作的给用户的进展。

// This event handler updates the progress bar. 
private void backgroundWorker1_ProgressChanged(object sender,
    ProgressChangedEventArgs e)
{
    this.progressBar1.Value = e.ProgressPercentage;
}

Refer to MSDN for more information about using this.

有关使用它的更多信息,请参阅 MSDN。

回答by Aleksey Shubin

If you are using .NET 4.5 or later, you can use async/await:

如果您使用 .NET 4.5 或更高版本,则可以使用async/await

var progress = new Progress<int>(value => progressBar.Value = value);
await Task.Run(() =>
{
    for (int i = 0; i < 100; i++)
    {
        ((IProgress<int>)progress).Report(i);
        Thread.Sleep(100);
    }
});

You need to mark your method with asynckeyword to be able to use await, for example:

您需要用async关键字标记您的方法才能使用await,例如:

private async void Button_Click(object sender, RoutedEventArgs e)