2009-04-11 11 views
0

私はいくつかの基本的なスレッドを行うサーバープログラムを書いています。いくつかのUIコントロールを更新する必要があり、すべてがスレッドセーフであるようにデリゲートを使用する方法を学びました。例えば、ここで私は、スレッドからのTextBoxコントロールを更新することができます私のデリゲートだ:.NETのスレッドのカウンタを更新する

Private Delegate Sub AddMessageToTXTDelegate(ByVal lst As TextBox, ByVal str1 As String) 
Private Sub AddMessageToTXT(ByVal txt As TextBox, ByVal str1 As String) 
    Try 
     If Me.InvokeRequired Then 
      Dim addTXT As New AddMessageToTXTDelegate(AddressOf AddMessageToTXT) 
      Me.BeginInvoke(addTXT, New Object() {txt, str1}) 
     Else 
      txt.Text = str1 
     End If 
    Catch ex As Exception 
     Console.WriteLine(ex.Message) 
     Throw (ex) 
    End Try 
End Sub 

は、今私は、カウンタを更新する必要があると私は同じパターンが適用されます考え出し。私は次のデリゲートをまとめました:

Private Delegate Sub IncrementCounterDelegate(ByVal ctr As Integer) 
Private Sub IncrementCounter(ByVal ctr As Integer) 
    Try 
     If Me.InvokeRequired Then 
      Dim incCtr As New IncrementCounterDelegate(AddressOf IncrementCounter) 
      Me.BeginInvoke(incCtr, New Object() {ctr}) 
     Else 
      ctr += 1 
     End If 
    Catch ex As Exception 
     Console.WriteLine(ex.Message) 
     Throw (ex) 
    End Try 
End Sub 

問題は私のカウンターが増分されていないことです。これをデバッグでトレースすると、 "ctr + = 1"文が実行されますが、実際のカウンタはゼロのままです。カウンターを参考にして渡すべきだと思っています。

誰でもアドバイスをいただけますか?ありがとう! CBF

答えて

1

System.Threading.Interlocked.Incrementを使用して達成することができる整数をインクリメントするスレッドセーフな方法\

。これを使用してデリゲートを避ける必要があります。

編集

デリゲートを使用しようとする理由がわかりません。任意のスレッドで実行可能な値オブジェクトをインクリメントします。他のスレッドからUIコントロールを更新することはできません。

このスレッドセーフを作成しようとする場合は、モニターを使用してロックを導入するか(例として)、インターロックのIncrementメソッドを使用する必要があります。

1

カウンタを値で渡しています。したがって、ctr += 1は、関数の引数をインクリメントします。カウンターを参照渡しするか、InterlockedIncrementというプライベートフィールドを増やす必要があります。デリゲートや呼び出しは不要です。

関連する問題