2012-02-21 10 views
1

VSTO/VBで、うまく動作するBackgroundWorkerを使用するプロジェクトがあります。これは、情報のWebページを呼び出すフォームです。 Webページにはしばらく時間がかかりますので、私はBackgroundWorkerでフォームを呼び出しています。StartupプロジェクトではないときにBackgroundWorkerがエラーを起こす

次に、BackgroundWorkerプロジェクトを追加したExcel Addinプロジェクトがあります。 Excel Addinプロジェクトからフォームを呼び出し、BackgroundWorkerを使用してWebページをリクエストすると、Webページが表示されます。しかし、BackgroundWorker1_RunWorkerCompletedメソッドの実行中に完了した作業によって、エラーメッセージが表示されます。

"クロススレッド操作が無効です:作成されたスレッド以外のスレッドからコントロール 'TabPage2'がアクセスされました。

Excel AddinプロジェクトからBackgroundWorkerプロジェクトを呼び出すと、なぜ機能しないのですか?

「スタートアッププロジェクト」としてBackgroundWorkerプロジェクトを設定すると、エラーは発生しません。 Excel AddinプロジェクトからこのBackgroundWorkerプロジェクトを呼び出すことと関係があります。

答えて

1

編集:非UIスレッドからRunWorkerAsync()を呼び出している可能性がありますか?

リボンクラスを持つExcel Addinプロジェクトがあります。 Ribbon1.vbはBackgroundWorkerのが呼び出されます、そこから第二のプロジェクト、のインスタンスを作成し、ボタンクリック方法があります:

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

すると、それが完了した後、BackgroundWorkerのは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は駅だったときrtup Projectでは、バックグラウンドワーカーは正しいスレッドを追跡し、完了時にラベルを正常に更新しました。スタートアッププロジェクトとしてExcelアドインを使用し、実行時にMySecondProjectをインスタンス化すると、バックグラウンド作業者は正しいスレッドを追跡できなくなっているようです。手動でInvokeまたはBeginInvokeをどこかに挿入して、バックグラウンド作業者が正しいスレッドを更新するのを手助けする必要がありますか?

1

したがって、リボンから起動したフォームから起動したBackgroundworkerは、処理の最後にコントロールを更新できないことが判明しました。リボンから起動されたフォームから起動しないフォームがスタートアッププロジェクトとして起動された理由はわかりませんが、そこにはUIスレッドのバックグラウンド作業者が失うトラックに対処する必要があることが判明しています。 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)) 
関連する問題