Обновление счетчика потока в .NET - PullRequest
0 голосов
/ 11 апреля 2009

Я пишу серверную программу, которая выполняет некоторые базовые потоки. Необходимо обновить некоторые элементы управления пользовательским интерфейсом, и я узнал, как использовать делегаты, чтобы все было поточно-ориентированным. Например, вот мой делегат, который позволяет мне обновлять элемент управления 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

Проблема в том, что мой счетчик не увеличивается. Когда я отслеживаю это с помощью отладки, выполняется оператор «ctr + = 1», но фактический счетчик остается равным нулю. Я думаю, что я должен передать счетчик по ссылке.

Кто-нибудь может дать здесь какой-нибудь совет? Спасибо!

\ CBF

Ответы [ 2 ]

1 голос
/ 11 апреля 2009

Вы передаете счетчик по значению, поэтому ctr += 1 увеличивает аргумент функции. Вам нужно передать счетчик по ссылке или просто увеличить частное поле с помощью InterlockedIncrement - без делегатов или вызова.

1 голос
/ 11 апреля 2009

Поточный безопасный способ увеличения целого числа может быть достигнут с помощью System.Threading.Interlocked.Increment . Вы должны использовать это и избегать делегата.

Редактировать

Я не уверен, почему вы пытаетесь использовать делегата. Ваш приращения объекта значения, который может быть сделан в любом потоке. Вы просто не можете обновить элементы управления пользовательского интерфейса из других потоков.

Если вы пытаетесь сделать этот потокобезопасным, то вам нужно ввести блокировку с помощью монитора (в качестве одного примера) или с помощью метода приращения в Interlocked.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...