我在进度条实时显示更新时遇到了一些麻烦。
这是我现在的代码
for (int i = 0; i < 100; i++)
{
progressbar1.Value = i;
Thread.Sleep(100);
}
但由于某种原因,当函数运行时,进度条显示为空,然后在函数完成运行之前没有任何内容。有人可以向我解释如何做到这一点?我是C#/ WPF的新手,所以我不能100%确定如何在不同的线程上实现Dispatcher(如其他帖子所见)来解决这个问题。
为了澄清,我的程序有一个按钮,按下时,从文本框中获取值,并使用API检索信息,并根据它创建标签。我希望在每行数据处理完毕后更新进度条。
这就是我现在所拥有的:
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);
}
}));
});
}
谢谢!
答案 0 :(得分:26)
如果您使用的是.NET 4.5或更高版本,则可以使用async/await:
using System;
using Oracle.ManagedDataAccess.Client;
using System.Configuration;
namespace vnext.Models
{
internal class dataHelper
{
OracleConnection cn = new OracleConnection(ConfigurationManager.ConnectionStrings["hr"].ConnectionString);
}
}
您需要使用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);
}
});
关键字标记您的方法才能使用async
,例如:
await
答案 1 :(得分:21)
管理以使其工作。我需要做的就是取而代之的是
progressBar1.value = i;
我只需要做
progressbar1.Dispatcher.Invoke(() => progressbar1.Value = i, DispatcherPriority.Background);
答案 2 :(得分:5)
您应该使用.NET中包含的BackgroundWorker,它为您提供了报告事件中后台线程进度的方法。创建BackGroundWorker的线程会自动调用此事件。
BackgroundWorker.ProgressChanged可用于向用户报告异步操作的进度。
// This event handler updates the progress bar.
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
有关使用此功能的详细信息,请参阅MSDN。