EDIT3:
我知道这个问题与其他人类似。其他问题中没有涉及的主要区别在于我需要通过两个单独的类来实现这一点。即,在MainWindow
中启动BGW并在DoWork
中使用耗时函数运行ConDB
- 方法。
我有两个班级MainWindow
和ConDB
。使用buttonclick我在ConDB中调用一个方法,这会花费一些时间。现在我需要我的进度条来更新循环的每次迭代。
为此,我有一个背景工作者的代码如下:
private void btnConvert_Click(object sender, RoutedEventArgs e)
{
ConDB con = new ConDB();
date = tbDatum.Text;
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += new DoWorkEventHandler(con.worker_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerAsync();
}
RunWorkerAsync()
将在ConDB中调用我的DoWork
- 方法,因此con.worker_DoWork
在ConDB中,我调用mw.worker.ReportProgress(progress)
来更新进度条,正如您所想,它会抛出InvalidOperationException:
调用线程无法访问此对象,因为另一个线程拥有它。
现在我读了很多关于使用Dispatcher.CurrentDispatcher.BeginInvoke
的内容,因为你无法从后台工作者线程访问UI线程。到目前为止一切都很好。
我现在的问题是,我不知道如何用Dispatcher
来解决这个问题,因为我不知道在哪里以及如何编写这段代码。
另外,我不确定我是否正在与背景工作者正确地做事。我是否需要在我的ConDB类中定义和实例化它,或者我可以保留它吗?
非常感谢任何有关教育我的想法,建议和帮助!
修改
public void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pbProgressBar.Value = e.ProgressPercentage;
}
抛出异常。
EDIT2:
因此,为了提供一个希望可重复的示例,这里是示例代码。
我从MainWindow调用此方法:
private void btnConvert_Click(object sender, RoutedEventArgs e)
{
ConDB con = new ConDB();
con.test();
}
这将是(在其他类ConDB中):
public void test()
{
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerAsync();
}
然后调用我更新进度条的DoWork方法:
public void worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 1000; i++)
{
percent++;
progress = percent * 100 / rows.Count();
worker.ReportProgress(progress);
}
}
ReportProgress然后调用:
public void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
mw.pbProgressBar.Value = e.ProgressPercentage;
}
我的目标首先是在MainWindow
开始背景工作,但是为了让我的生活更轻松和测试,我现在称之为启动BGW的方法test
。