BackgroundWorker вызывает ошибку, когда не запускается проект - PullRequest
1 голос
/ 22 февраля 2012

У меня есть проект в VSTO / VB, использующий BackgroundWorker, который работает нормально.Это форма, которая требует веб-страницы с информацией.Веб-страница может занять некоторое время, поэтому у меня есть форма, вызываемая с помощью BackgroundWorker.

Затем у меня есть проект Excel Addin, в который был добавлен проект BackgroundWorker.Когда я вызываю форму из проекта Excel Addin и использую BackgroundWorker для запроса веб-страницы, она нормально захватывает веб-страницу.Но работа, выполненная после завершения, во время метода BackgroundWorker1_RunWorkerCompleted, приводит к сообщению об ошибке:

«Операция с несколькими потоками недопустима: доступ к элементу управления TabPage2 осуществляется из потока, отличного от потока, в котором он был создан."

Почему проект BackgroundWorker не работает при вызове из проекта Addin для Excel?

Я отмечаю, что когда я задаю проект BackgroundWorker в качестве" Startup Project ", ошибка не генерируется.Это как-то связано с вызовом этого проекта BackgroundWorker из проекта Excel Addin.

Ответы [ 2 ]

1 голос
/ 23 февраля 2012

Итак, выясняется, что Backgroundworker, запущенный из формы, запущенной с ленты, не может обновить элемент управления в конце обработки. Я не уверен, почему он работает с формой, запущенной как проект запуска, в то время как он не работает с формой, запущенной с ленты, но это так - оказывается, что вам нужно иметь дело с потерей трека Backgroundworker потока пользовательского интерфейса .

Использование MethodInvoker работает, как в следующем фрагменте:

Imports System.Windows.Forms

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        [do nothing]
    End Sub

    Private myString As String = "This is my string"

    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

        If Label1.InvokeRequired Then
            Dim mi As MethodInvoker = AddressOf UpdateFormText
            Label1.BeginInvoke(mi)
        Else
            Label1.Text = myString
        End If

    End Sub

    Private Sub UpdateFormText()
        Label1.Text = myString + " (BeginInvoked)"
    End Sub

End Class

Лучшим ответом в VS2010 будет использование встроенного MethodInvoker вместо второй функции:

Me.Invoke(CType(Sub() Me.Label1.Text = "This is my string", MethodInvoker))
1 голос
/ 22 февраля 2012

Редактировать: Может быть, я вызываю RunWorkerAsync () из потока, не являющегося пользовательским интерфейсом?

У меня есть проект Excel Addin с классом ленты.В Ribbon1.vb есть метод нажатия кнопки, который создает экземпляр второго проекта, из которого будет вызываться фоновый работник:

Private Sub Btn_Click(ByVal sender As System.Object, ByVal e As Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs) Handles Btn.Click

    Dim MySecondProject As SecondProject.Form1 = New SecondProject.Form1()
    MySecondProject.Show()

End Sub

MySecondProject затем вызывает BackgroundWorker из своего собственного метода нажатия кнопки, как:

BackgroundWorker1.RunWorkerAsync()

Затем, после его завершения, фоновый работник пытается обновить метку в MySecondProject:

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

    SuccessLabel.Text = "Success!"

End Sub

Когда MySecondProject был Startup Project, фоновый работник отслеживал правильный потоки обновил ярлык успешно после завершения.С надстройкой Excel в качестве запускаемого проекта и созданием экземпляра MySecondProject во время выполнения фоновый работник, похоже, потерял правильную нить.Должен ли я вручную вставлять куда-нибудь Invoke или BeginInvoke, чтобы помочь фоновому специалисту отслеживать правильный поток для обновления?

...