Komunikasi lintas thread dan pembaruan lapangan di VB.NET

Saya mengalami masalah dalam membuat komunikasi lintas-thread/pembaruan lapangan berfungsi dengan baik di program VB.NET 2010 saya. Saya mencoba memperbarui bidang di formulir utama saya setiap kali utas yang saya mulai mengadakan acara. Berikut ini versi sederhana dari kode saya:

Bentuk utama saya:

Public Class Main
    ' stuff

    ' Eventually, startProcessing gets called:
    Private Sub startProcessing()
        Dim processingClass = New MyProcessingClass("whatever")
        AddHandler processingClass.processStatusUpdate, AddressOf handleProcessStatusUpdate
        Dim processingThread = New Thread(AddressOf processingClass.process)
        processingThread.Start()
    End Sub

    Private Sub handleProcessStatusUpdate(statusUpdate As String)
        txtMainFormTextBox.Text = statusUpdate ' InvalidOperationException
        ' "Cross-threaded operation not valid: Control 'txtMainFormTextBox' accessed from a thread other than the thread it was created on"
    End Sub
End Class

Kelas yang mengangkat acara:

Public Class MyProcessingClass
    Private whatever As String    

    Public Event processStatusUpdate(status As String)

    Public Sub New(inWhatever As String)
        whatever = inWhatever
    End Sub

    Public Sub process()
        ' do some stuff
        RaiseEvent processStatusUpdate(whatever)
    End Sub
End Class

Seperti yang Anda lihat, handler di kelas utama saya tidak memiliki akses ke TextBox yang saya perlukan karena dipicu oleh thread yang berbeda (menurut saya). Saya telah mencoba sejumlah pendekatan lain agar ini berfungsi, termasuk:

  1. Memindahkan event handler ke MyProcessingClass, dan meneruskan txtMainFormTextBox dengan referensi (ByRef) ke kelas.
  2. Memiliki thread sebenarnya yang dimulai di dalam MyProcessingClass, bukan Main.

Tidak ada satupun yang berhasil. Jelas ada konsep yang saya lewatkan di sini. Apa cara terbaik untuk menyelesaikannya? Terima kasih!


person Mike Cialowicz    schedule 24.01.2011    source sumber


Jawaban (1)


Anda perlu memperbarui kotak teks di thread UI dengan memanggil BeginInvoke.


Anda harus menggunakan BackgroundWorker komponen, yang melakukan semuanya ini untuk Anda.
Cukup tangani kejadian DoWork dan ProgressChanged.

person SLaks    schedule 24.01.2011
comment
Masalah dengan BeginInvoke adalah saya tidak bisa meneruskan agruments ketika saya menggunakannya, jadi saya tidak bisa menggunakan statusString saya. Saya akan memeriksa BackgroundWorker... - person Mike Cialowicz; 24.01.2011
comment
@Mike: Anda dapat meneruskan argumen ke BeginInvoke. Cukup gunakan Action(Of String). Namun, Anda sebaiknya menggunakan BackgroundWorker saja. - person SLaks; 24.01.2011