2011-01-24 2 views
0

VB.NET 2010プログラムでクロススレッド通信/フィールド更新が正常に動作するにはいくつか問題があります。私が開始したスレッドがイベントをスローするたびに、私のメインフォーム上のフィールドを更新しようとしています。ここに私のコードの簡易版だ:VB.NETでクロススレッド通信とフィールド更新

私のメインフォーム:

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 

イベントを発生させるクラス:

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 

あなたが見ることができるように、私のメインクラスのハンドラは、」doesnの私はそれが別のスレッド(私は思う)によってトリガされたので、私が必要とするTextBoxにアクセスできません。私には、この作業を取得するために、他の多数のアプローチを試してみた:

  1. MyProcessingClassにイベントハンドラを移動し、クラスへの参照(ByRefの)によってtxtMainFormTextBoxを渡します。
  2. Mainの代わりにMyProcessingClassの内部で実際のスレッドが開始されています。

いずれも機能していません。明らかに、私がここで欠けている概念があります。これを行うための最善の方法は何ですか?ありがとう!

答えて

2

BeginInvokeを呼び出して、UIスレッドのテキストボックスを更新する必要があります。


BackgroundWorker componentを使用する必要があります。これはすべてこれを行います。
DoWorkイベントとProgressChangedイベントを処理するだけです。

+0

'BeginInvoke'の問題は、私が使用しているときに私が手段を渡すことができないので、私の' statusString'を使うことができないことです。私はBackgroundWorkerを調べます... –

+0

@Mike: 'BeginInvoke'に引数を渡すことができます。 'Action(String(String)) 'を使うだけです。ただし、代わりにBackgroundWorkerを使用する必要があります。 – SLaks

関連する問題