1

我有一个具有许多属性的类,它们是IntegerSingle。我想以多线程方式使用该类,以便可以将属性用作累加器(该类是报告方案的基础)。所以我希望能够做这样的事情:

Public Class ReportTotals
    Property Count As Integer
    Property Total As Single
    Property Tax As Single
    Property Shipping As Single
    Property ItemsSold As Integer

    Public Function GetReport() As String
    ...
    End Function
End Class

Public Function BuildReportData As ReportTotals

    Dim myReport As New ReportTotals
    With myReport
        Parallel.ForEach(UserSales, Sub(userSale)
                .Count += 1
                .Total += userSale.Total
                .Tax += userSale.Tax
                .Shipping += userSale.Shipping
                .ItemsSold += userSale.ItemsSold

                'more complicated stuff and property assignments

            End Sub)
    End With
End Function

根据我的研究,我知道这一点Integer并且Single是原子的,但我不确定这是否扩展到作为类的一部分的整数。我不想假设,因为多线程错误可能会在以后出现并咬我。

更新:显然,Single不是线程安全的,所以我必须在那个上使用锁,但是呢Integer

4

4 回答 4

3

您可以使用Interlocked.Increment以原子方式递增整数,即使它们是类成员。

于 2013-04-22T20:51:58.840 回答
1

这听起来像你想要的是与 local state 一起工作的重载Parallel.ForEach()

localInit委托中,您将创建一个新实例,ReportTotals并在锁定localFinally中将本地值添加到全局值。ReportTotals

于 2013-04-22T22:26:11.833 回答
0

也许SyncLock是您正在寻找的。

 Public Sub sale(s As String)
     SyncLock _lock
          //'thread safe code'
     End SyncLock
 End Sub

 Public Function BuildReportData as ReportTotals

 Dim myReport As New ReportTotals
 With myReport
     Parallel.ForEach(UserSales, sale(userSale))

 End Function
于 2013-04-22T21:02:04.043 回答
0

至少在有人有更好的主意之前,我决定做的是ReportTotals在例程中创建大量对象Parallel.ForEach并将它们全部放入ConcurrentBag. 然后,在Parallel.ForEach语句结束后,我使用常规语句将对象中的For Each所有值累积到一个新对象中,然后我将其返回。ReportTotalsConcurrentBagReportTotals

所以我正在做这样的事情:

Public Class ReportTotals
    Property Count As Integer
    Property Total As Single
    Property Tax As Single
    Property Shipping As Single
    Property ItemsSold As Integer

    Public Function GetReport() As String
    ...
    End Function
End Class

Public Function BuildReportData As ReportTotals

    Dim myReport As New ReportTotals
    Dim myReports As New ConcurrentBag(Of ReportTotals)

    Paralle.ForEach(UserSales, Sub(userSale)
            Dim workingReport As New ReportTotals
            With workingReport
                .Count += 1
                .Total += userSale.Total
                .Tax += userSale.Tax
                .Shipping += userSale.Shipping
                .ItemsSold += userSale.ItemsSold

                'more complicated stuff and property assignments

            End With
        End Sub)

    For Each report In myReports 
        With myReport
            .Count += report.Count
            .Total += report.Total
            .Tax += report.Tax
            .Shipping += report.Shipping
            .ItemsSold += report.ItemsSold
        End With
    Next

    Return myReport
End Function
于 2013-04-22T22:07:54.687 回答