多线程不输出全部

时间:2014-11-04 09:39:52

标签: vb.net multithreading

我不确定我做错了什么。我有一个简单的程序使用线程池来执行9个任务。每个任务都会启动三个新线程来检索数据。然后调用线程处理结果。它们都应该以不同的时间执行,然后将结果输出到即时窗口。但并非所有任务实际输出任何东西。我通常得到7到8个结果。我无法预测哪些结果会输出;它是随机的。为什么不是所有结果都输出?

Class Work3

    Sub mainLoop()

        Dim callback As New WaitCallback(AddressOf DoOneCustomer)

        For loopCt As Integer = 1 To 9

            'Data in
            Dim dataIn As New DataIn("Cust" & loopCt, loopCt)

            'run code on the thread pool
            ThreadPool.QueueUserWorkItem(callback, dataIn)

        Next

    End Sub

    Function DoOneCustomer(ByVal DataIn2 As Object) As Boolean
        Dim DataIn As DataIn = CType(datain2, Datain)

        Dim Tub As New DataContainer(DataIn.CustID, DataIn.Int)

        'start new data threads
        'get data in parallel
        Dim t1 As New Thread(AddressOf GetData1)
        Dim t2 As New Thread(AddressOf GetData2)
        Dim t3 As New Thread(AddressOf GetData3)
        t1.Start(Tub)
        t2.Start(Tub)
        t3.Start(Tub)

        'join all three threads to ensure finished getting data
        t1.Join()
        t2.Join()
        t3.Join()

        If MakeDecision(Tub) Then

            'process results in-line; no new thread
            doProcessData(Tub)

        End If

        Return True

    End Function

    Function MakeDecision(ByRef Tub As DataContainer) As Boolean
        Return True
    End Function

    Sub doProcessData(ByVal myTub As DataContainer)

        Debug.Print(myTub.Data1.QBName & _
                    " End bal: " & myTub.Data1.EndBal.ToString("#,##0") & _
                    " Inv1 " & myTub.Data2.Total.ToString("#,##0") & _
                    " Inv2 " & myTub.Data3.Total.ToString("#,##0"))
    End Sub

    Sub GetData1(ByVal myTub2 As Object)
        Dim myTub As dataContainer = CType(myTub2, DataContainer)
        Dim d As New DetailData
        d.QBName = myTub.CustID
        d.BeginBal = myTub.Int * 10000 + myTub.Int
        d.EndBal = myTub.Int * 100000 + myTub.Int
        Dim Num As Integer = Calculate(myTub.Int)

        'put data
        myTub.Data1 = d
    End Sub
    Sub GetData2(ByVal myTub2 As Object)
        Dim myTub As dataContainer = CType(myTub2, DataContainer)
        Dim inv As New InvoiceData
        inv.QbCustName = myTub.CustID
        inv.TxnDate = DateAdd(DateInterval.Day, New Random(1).Next(1, 30), Now)
        inv.Total = myTub.Int * 1000 + myTub.Int
        Dim Num As Integer = Calculate(myTub.Int)

        'put data
        myTub.Data2 = inv
    End Sub
    Sub GetData3(ByVal myTub2 As Object)
        Dim myTub As dataContainer = CType(myTub2, DataContainer)
        Dim inv As New InvoiceData
        inv.QbCustName = myTub.CustID
        inv.TxnDate = DateAdd(DateInterval.Day, New Random(1).Next(1, 30), Now)
        inv.Total = myTub.Int * 100
        Dim Num As Integer = Calculate(myTub.Int)

        'put data
        myTub.Data3 = inv
    End Sub

End Class

Class DataIn
    Public Int As Integer
    Public CustID As String
    Public Sub New(ByVal _CustID As String, ByVal _Int As Integer)
        Int = _Int
        CustID = _CustID
    End Sub
    Public Sub New()
    End Sub
End Class

Class DataContainer
    Public Int As Integer
    Public CustID As String
    Public Data1 As DetailData
    Public Data2 As InvoiceData
    Public Data3 As InvoiceData
    Public Sub New(ByVal _CustID As String, ByVal _Int As Integer)
        Int = _Int
        CustID = _CustID
    End Sub
    Public Sub New()
    End Sub
End Class

Class DetailData
    Public QBName As String
    Public BeginBal As Decimal
    Public EndBal As Decimal
End Class

Class InvoiceData
    Public QbCustName As String
    Public TxnDate As Date
    Public Total As Decimal
End Class

'calculate fibonacci to increase calculation time by varying amounts
Public Function Calculate(ByVal n As Integer) As Integer
    If n <= 1 Then
        Return n
    End If
    Return Calculate(n - 1) + Calculate(n - 2)
End Function

输出看起来像这样

Cust1 End bal: 100,001 Inv1 1,001 Inv2 100
Cust4 End bal: 400,004 Inv1 4,004 Inv2 400
Cust2 End bal: 200,002 Inv1 2,002 Inv2 200
Cust7 End bal: 700,007 Inv1 7,007 Inv2 700
Cust6 End bal: 600,006 Inv1 6,006 Inv2 600
Cust5 End bal: 500,005 Inv1 5,005 Inv2 500
Cust8 End bal: 800,008 Inv1 8,008 Inv2 800
Cust9 End bal: 900,009 Inv1 9,009 Inv2 900

.Net fiddle

1 个答案:

答案 0 :(得分:0)

我认为问题出在Debug.Print上。我认为使用Debug.Print来评估我的代码是一个有缺陷的想法。为什么我认为调试窗口可以处理多个同时输入。

使用MsgBox作为输出时,代码按预期执行。输出所有数据。对于VB.net,多个Msgbox窗口不是问题。

我也试过在代码中放一个Thread.Sleep。有了它,它也可以正常工作。大概是因为输出不再同时进入调试窗口。

所以最后问题不在于代码本身,而在于输出设备。需要重写代码以考虑输出设备的限制。

相关问题