単純な BackgroundWorker を実装しようとすると、悪名高い「クロススレッド操作が無効です」という例外が発生します。SOに関する多くの関連する質問を含め、この件に関して見つけることができるすべてを読むのに何時間も費やしましたが、私はそれを理解していません.
DoWork() メソッドを持つ単純な winform があります。
- 実行する作業を表すデリゲートが必要です。
- を作成し、デリゲートをイベント
BackgroundWorker
に割り当てます。DoWork
- を呼び出します
RunWorkerAsync()
。
によって呼び出された関数はRunWorkerCompleted()
、フォームのラベルを更新しようとしますが、スレッド間例外をスローします。
Public Class MyForm
Public Sub DoWork(workToDo As DoWorkEventHandler)
Dim worker As New BackgroundWorker()
worker.WorkerReportsProgress = True
worker.WorkerSupportsCancellation = True
AddHandler worker.DoWork, workToDo
AddHandler worker.RunWorkerCompleted, AddressOf WorkerCompleted
worker.RunWorkerAsync()
End Sub
Private Sub WorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
resultLabel.Text = "Done!" ' Exception thrown here
End Sub
End Class
WorkerCompleted
したがって、バックグラウンド スレッドで実行されているように見えます。私は実用的な解決策に近づいていますか、それとも基本的なことを理解していませんか?
更新: 謎の修正
ばかげた運で「修正」を発見しました。アプリケーションをさらに調べる必要があります。これは VSTO Excel アドインの一部です。Show()
リボンの Load イベントでフォームをインスタンス化し、ボタンがクリックされたときに呼び出していました。これにより例外が発生しました。
Private Sub Ribbon1Load(ByVal sender As System.Object, ByVal e As RibbonUIEventArgs) Handles MyBase.Load
mProcessing = New MyForm()
End Sub
Private Sub Button1Click(sender As System.Object, e As RibbonControlEventArgs) Handles Button1.Click
mProcessing.Show()
mProcessing.DoWork(AddressOf UpdateData)
End Sub
Click ハンドラーに移動mProcessing = New MyForm()
すると、例外がなくなります。すべてがうまくいっています。私はコードを数回前後に動かしましたが、問題/解決策に自信があります。