0

I am building a VSTO Excel Add In for Excel 2010... I have a form that the user selects a query and then the populates the sheet appropriately from a table.

I want to report progress as the operation is happening. The operation exists in a seperate class than the UI. Thus I construct the class (ol and ole) and call the method within the DoWork handler.

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();
    }

Then inside the class, specifically the method i am using has a argument set for BackgroundWorker bw. This is how i pass in the worker. Then when appropriate i intend to Update the progress by calling 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++;
    }

This script runs successfully, however the progress bar is not changed at all... Thoughts?

EDIT

    // 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);

EDIT 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;

ERROR I am now seeing this error that i was not seeing before.

`An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

Additional information: Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on.`

LCaraway
  • 1,257
  • 3
  • 20
  • 48
  • You haven't shown the initialisation of the BackgroundWorker object, it has a property called WorkerReportsProgress, this needs to be set to true – JayV May 08 '18 at 22:03
  • It is set to true. – LCaraway May 08 '18 at 22:03
  • Only other thing I can think of is: Does the ProgressBar have appropriate values for Min and Max values? – JayV May 09 '18 at 12:39
  • just made sure to add those. Still no luck. Now I am getting this error... `Additional information: Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on.` – LCaraway May 09 '18 at 13:52
  • The error pretty much tells you the problem. You can't update a UI control from anything other than the UI thread. You need to `Invoke` on the UI thread to update your control. What does `backgroundWorker3_ProgressChanged` look like? – Matt Burland May 09 '18 at 14:02
  • I've included it in my script above. – LCaraway May 09 '18 at 14:04
  • Another Consideration that i just thought of is that this is to be used in a VSTO Excell Add In. I wonder if they allow multi-threading... – LCaraway May 09 '18 at 14:15
  • Possible duplicate of [BackgroundWorker Not working in VSTO](https://stackoverflow.com/questions/2449515/backgroundworker-not-working-in-vsto) – Fang May 09 '18 at 14:35

1 Answers1

2

VSTO has issues with the BackgroundWorker component. You need to set the synchronization context in order to get it to work.

System.Threading.SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());

bw = new BackgroundWorker();
...
bw.RunWorkerAsync();
JayV
  • 3,238
  • 2
  • 9
  • 14
  • I created the BackgroundWorker in the button event handler that started my process – JayV May 09 '18 at 14:33
  • This worked! Thanks! - What is the SynchronizationContext? Do i need to call it every time or can i move this to the top of the script? – LCaraway May 09 '18 at 14:44