.NET中的线程更新计数器

时间:2009-04-11 13:17:25

标签: .net multithreading

我正在编写一个执行一些基本线程的服务器程序。它需要更新一些UI控件,我学会了如何使用委托,以便一切都是线程安全的。例如,这是我的委托,它允许我从线程更新TextBox控件:

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

问题是我的计数器没有递增。当我使用debug跟踪它时,会执行“ctr + = 1”语句,但实际计数器保持为零。我想我应该通过参考传递计数器。

有人可以在这提供一些建议吗?谢谢!

\ CBF

2 个答案:

答案 0 :(得分:1)

使用System.Threading.Interlocked.Increment可以实现增加整数的线程安全方法。您应该使用它并避免委托。

修改

我不确定你为什么试图使用委托。您递增一个值对象,可以在任何线程上完成。您无法从其他线程更新UI控件。

如果你试图使这个线程安全,那么你需要使用Monitor(作为一个例子)或使用Interlocked的Increment方法引入锁定。

答案 1 :(得分:1)

您正在按值传递计数器,因此ctr += 1会增加函数的参数。您需要通过引用传递计数器,或者只使用InterlockedIncrement增加一个私有字段 - 不需要委托或调用。