BackgroundWorker Не работает во ВСТО - PullRequest
9 голосов
/ 15 марта 2010

У меня есть фоновый работник. Прежде чем вызвать работника, я отключаю кнопку и делаю gif видимым. Затем я вызываю метод runworkerasync, и он работает до конца. На «RunWorkerCompleted ()» я получаю ошибку перекрестного потока. Есть идеи почему?

    private void buttonRun_Click(object sender, EventArgs e)
    {
        if (comboBoxFiscalYear.SelectedIndex != -1 && !string.IsNullOrEmpty(textBoxFolderLoc.Text))
        {
            try
            {
                u = new UpdateDispositionReports(
                    Convert.ToInt32(comboBoxFiscalYear.SelectedItem.ToString())
                    , textBoxFolderLoc.Text
                    , Properties.Settings.Default.TemplatePath
                    , Properties.Settings.Default.ConnStr);
                this.buttonRun.Enabled = false;
                this.pictureBox1.Visible = true;

                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                bw.RunWorkerAsync();
                //backgroundWorker1.RunWorkerAsync();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unable to process.\nError:" + ex.Message, Properties.Settings.Default.AppName);
            }
        }
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        buttonRun.Enabled = true;
        pictureBox1.Visible = false;
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        u.Execute();
    }

Ответы [ 2 ]

22 голосов
/ 09 декабря 2010

Кажется, это проблема с VSTO и BackgroundWorker.

Решение здесь .

В основном вам нужно позвонить

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

прежде чем позвонить RunWorkerAsync. Прекрасно работает.

Чтобы не создавать экземпляры объекта каждый раз, когда у вас есть статический член в главном классе AddIn, и вы можете использовать его повторно Таким образом, вы создаете экземпляр только один раз.

2 голосов
/ 15 марта 2010

кое-что о VSTO, работающем в фоновом режиме в том же потоке, что и элементы управления. Точно сказать не могу. Я должен был проверить InvokeRequired

    private void buttonRun_Click(object sender, EventArgs e)
    {
        if (comboBoxFiscalYear.SelectedIndex != -1 && !string.IsNullOrEmpty(textBoxFolderLoc.Text))
        {
            try
            {
                u = new UpdateDispositionReports(
                    Convert.ToInt32(comboBoxFiscalYear.SelectedItem.ToString())
                    , textBoxFolderLoc.Text
                    , Properties.Settings.Default.TemplatePath
                    , Properties.Settings.Default.ConnStr);
                this.buttonRun.Enabled = false;
                this.pictureBox1.Visible = true;

                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                bw.RunWorkerAsync();
                //backgroundWorker1.RunWorkerAsync();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unable to process.\nError:" + ex.Message, Properties.Settings.Default.AppName);
            }
        }
    }
    delegate void ReenableRunCallback();

    private void ReenableRun()
    {
        if (this.buttonRun.InvokeRequired)
        {
            ReenableRunCallback r = new ReenableRunCallback(ReenableRun);
            this.buttonRun.Invoke(r, null);
        }
        else
            this.buttonRun.Enabled = true;
    }
    private void HideProgress()
    {
        if (this.pictureBox1.InvokeRequired)
        {
            ReenableRunCallback r = new ReenableRunCallback(HideProgress);
            this.pictureBox1.Invoke(r, null);
        }
        else
            this.pictureBox1.Visible = false;
    }

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        ReenableRun();
        HideProgress();
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        u.Execute();
    }
...