我正在为Excel 2010构建VSTO Excel Add In ...我有一个表单,用户选择一个查询,然后从表中适当填充表单。
我想在操作发生时报告进度。该操作存在于与UI不同的单独类中。因此,我构造了类(ol和ole)并在DoWork
处理程序中调用该方法。
private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker)sender;
if (!_isExtended)
{
oneline ol = new oneline();
ol.buildOneline(this._wheres,worker );
}
else
{
ExtendedOneline ole = new ExtendedOneline();
ole.buildExtendedOneline(this._wheres,worker);
}
//worker.ReportProgress();
e.Result = "COMPLETE!";
}
private void backgroundWorker3_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker3_WorkerCOmpleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show(e.Result.ToString());
this.Close();
}
然后在类中,特别是我正在使用的方法为BackgroundWorker bw
设置了一个参数。这就是我传给工人的方式。然后在适当的时候,我打算通过调用bw.ReportProgress(PercentComplete)
public void buildOneline(List<WhereStatement> wheres, BackgroundWorker bw)
{
....
....
double count = joinedWells.Count;
double i = 1;
foreach (var well in joinedWells)
{
double PercentComplete = 100 * (i / count);
bw.ReportProgress((int)PercentComplete);
....
....
i++;
}
此脚本成功运行,但进度条根本没有改变...想法?
编辑
// backgroundWorker3
this.backgroundWorker3.WorkerReportsProgress = true;
this.backgroundWorker3.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker3_ProgressChanged);
this.backgroundWorker3.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker3_DoWork);
编辑2
//progressBar1
this.progressBar1.Location = new System.Drawing.Point(10, 340);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(583, 20);
this.progressBar1.Step = 1;
this.progressBar1.TabIndex = 15;
this.progressBar1.Maximum = 100;
this.progressBar1.Minimum = 0;
错误 我现在看到的是我以前没见过的这个错误。
`类型&#39; System.InvalidOperationException&#39;的未处理异常发生在System.Windows.Forms.dll
中附加信息:跨线程操作无效:控制&#39; progressBar1&#39;从其创建的线程以外的线程访问。
答案 0 :(得分:2)
VSTO存在BackgroundWorker组件问题。您需要设置同步上下文才能使其工作。
System.Threading.SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
bw = new BackgroundWorker();
...
bw.RunWorkerAsync();