Daniel Gee
Daniel Gee

Reputation: 438

Variables calculating from one thread to another

I have a Sub which I'm running multiple times in separate threads. I have running total variables in the Sub. The values of the variables seem to get added between threads. What am I doing wrong here?

Code to call the function from multiple threads:

Dim theradArray(dt.Rows.Count) As System.Threading.Thread 'Array of thread for each line
Dim threads As List(Of System.Threading.Thread) = New List(Of System.Threading.Thread)
Dim thr As System.Threading.Thread = New System.Threading.Thread(AddressOf 
StockTransactionReport)
threads.Add(thr)
threads.LastOrDefault().Start(stockTransaction)

The Sub:

Private Sub StockTransactionReport(ByVal StockTransaction As Object)
    'Database query happens here
    Dim RunningTotals As RunningTotals
    NewRunningTotalsSales.dGTAvgCost += RunningTotals.dGTAvgCost
    'File is written to here
End Sub

Upvotes: 1

Views: 399

Answers (1)

djv
djv

Reputation: 15774

There are better ways of doing this, but this might work in your case without too much effort. Use Static to declare that the object instance is the same across all calls to the method. (btw you never created an instance, so your question mustn't show your actual code)

Private Sub StockTransactionReport(ByVal StockTransaction As Object)
    'Database query happens here
    Static RunningTotals As New RunningTotals()
    NewRunningTotalsSales.dGTAvgCost += RunningTotals.dGTAvgCost
    'File is written to here
End Sub

And in the RunningTotals class, which we don't see, you can use a thread-safe collection to account for adds coming from different threads

Public Class RunningTotals
    Private numbers As New Concurrent.ConcurrentBag(Of Double)
    Public Sub Add(value As Double)
        numbers.Add(value)
    End Sub
    Public ReadOnly Property dGTAvgCost As Double
        Get
            Return numbers.Average()
        End Get
    End Property
End Class

It occurred to me your RunningTotals may be a class with all shared members, in which case your original code was... right, and you don't need to create an instance, but you also wouldn't need to create a variable for that either so I'm not sure...

Upvotes: 1

Related Questions