如何允许 backgroundworker 更新 UI 并为其设置 (metro) progressring?
How to allow backgroundworker to update UI and set (metro) progressring for it?
半年前才接触c#,正在学习中。
我有一个程序可以帮助我工作,它与我工作场所的 4 种数据库进行通信。它工作得很好,但现在我想设计让它更酷,但是当我想设置一个进度环时我卡住了,因为我的方法在与我的数据库通信时冻结 UI。
我想设置一个后台工作者,我尝试了所有我发现的甚至调用的东西,但没有任何效果。
public partial class MainWindow : MetroWindow
{
BackgroundWorker workerThread = null;
public MainWindow()
{
InitializeComponent();
InstantiateWorkerThread();
progressrinG.IsActive = true;
}
private void InstantiateWorkerThread()
{
workerThread = new BackgroundWorker();
workerThread.ProgressChanged += WorkerThread_ProgressChanged;
workerThread.DoWork += WorkerThread_DoWork;
workerThread.RunWorkerCompleted += WorkerThread_RunWorkerCompleted;
workerThread.WorkerReportsProgress = true;
//workerThread.WorkerSupportsCancellation = true;
}
private void WorkerThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void WorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void WorkerThread_DoWork(object sender, DoWorkEventArgs e)
{
//My huge method,asking 4 database that would update UI too
//... Textboxes,Grids,Expanders.
}
private void Button3_Click(object sender, RoutedEventArgs e)
{
workerThread.RunWorkerAsync();
while (workerThread.IsBusy)
{
progressrinG.Visibility = Visibility.Visible;
}
}
}
即使使用 Invoke,当我按下按钮时,5-10 秒后它完成了我的方法,但是我的应用程序在执行时被冻结并且我看不到进度条。
关于我做错了什么有什么想法吗?或者我该怎么办?提前致谢!
不要从 WorkerThread_DoWork
中的工作线程更新 UI,而是通过 WorkerThread_ProgressChanged
中的 UI 线程更新。
通过传递任意百分比进度的工作人员定期调用 worker.ReportProgress
,以便调用 WorkerThread_ProgressChanged
。仅当百分比差异发生变化时才更新 UI 以防止 UI 更新耗尽。
抱歉,如果您已经找到了一个例子,但我最近自己做了这个。它略有不同,但可以根据您的需要进行调整。我有一个微调器,我从单击按钮开始,它也执行我的方法,然后我有一个标签,我使用 ReportProgress 更新标签,就像 MickyD 建议的那样。
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progress = e.ProgressPercentage;
progressLabel.Text = "Creating User " + totalUserCreatedCount + " of " + rowCount;
}
我经历了一个循环,每次我再次从循环的顶部开始时都会报告。我这样调用 ProgressChanged
backgroundWorker.ReportProgress((100 * i) / rowCount);
行数是我要循环的总次数。
希望这有意义吗?
半年前才接触c#,正在学习中。 我有一个程序可以帮助我工作,它与我工作场所的 4 种数据库进行通信。它工作得很好,但现在我想设计让它更酷,但是当我想设置一个进度环时我卡住了,因为我的方法在与我的数据库通信时冻结 UI。 我想设置一个后台工作者,我尝试了所有我发现的甚至调用的东西,但没有任何效果。
public partial class MainWindow : MetroWindow
{
BackgroundWorker workerThread = null;
public MainWindow()
{
InitializeComponent();
InstantiateWorkerThread();
progressrinG.IsActive = true;
}
private void InstantiateWorkerThread()
{
workerThread = new BackgroundWorker();
workerThread.ProgressChanged += WorkerThread_ProgressChanged;
workerThread.DoWork += WorkerThread_DoWork;
workerThread.RunWorkerCompleted += WorkerThread_RunWorkerCompleted;
workerThread.WorkerReportsProgress = true;
//workerThread.WorkerSupportsCancellation = true;
}
private void WorkerThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void WorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void WorkerThread_DoWork(object sender, DoWorkEventArgs e)
{
//My huge method,asking 4 database that would update UI too
//... Textboxes,Grids,Expanders.
}
private void Button3_Click(object sender, RoutedEventArgs e)
{
workerThread.RunWorkerAsync();
while (workerThread.IsBusy)
{
progressrinG.Visibility = Visibility.Visible;
}
}
}
即使使用 Invoke,当我按下按钮时,5-10 秒后它完成了我的方法,但是我的应用程序在执行时被冻结并且我看不到进度条。
关于我做错了什么有什么想法吗?或者我该怎么办?提前致谢!
不要从 WorkerThread_DoWork
中的工作线程更新 UI,而是通过 WorkerThread_ProgressChanged
中的 UI 线程更新。
通过传递任意百分比进度的工作人员定期调用 worker.ReportProgress
,以便调用 WorkerThread_ProgressChanged
。仅当百分比差异发生变化时才更新 UI 以防止 UI 更新耗尽。
抱歉,如果您已经找到了一个例子,但我最近自己做了这个。它略有不同,但可以根据您的需要进行调整。我有一个微调器,我从单击按钮开始,它也执行我的方法,然后我有一个标签,我使用 ReportProgress 更新标签,就像 MickyD 建议的那样。
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progress = e.ProgressPercentage;
progressLabel.Text = "Creating User " + totalUserCreatedCount + " of " + rowCount;
}
我经历了一个循环,每次我再次从循环的顶部开始时都会报告。我这样调用 ProgressChanged
backgroundWorker.ReportProgress((100 * i) / rowCount);
行数是我要循环的总次数。
希望这有意义吗?