Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 多线程不输出所有_Vb.net_Multithreading - Fatal编程技术网

Vb.net 多线程不输出所有

Vb.net 多线程不输出所有,vb.net,multithreading,Vb.net,Multithreading,我不确定我做错了什么。我有一个使用线程池执行9个任务的简单程序。每个任务启动三个新线程来检索数据。然后调用线程处理结果。它们都应该以不同的时间执行,然后将结果输出到即时窗口。但并非所有任务都会输出任何内容。我通常得到7到8个结果。我无法预测将输出哪些结果;这是随机的。为什么不是所有结果都输出 Class Work3 Sub mainLoop() Dim callback As New WaitCallback(AddressOf DoOneCustomer)

我不确定我做错了什么。我有一个使用线程池执行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

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

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

我还试着在代码中加入一个线程。这样做也很好。这大概是因为输出不再同时命中调试窗口


因此,最终问题不在于代码本身,而在于输出设备。需要重新编写代码以考虑输出设备的限制。

在DoOneCustomer中,是浴缸还是浴缸?应该是浴缸。这在VB.net中有什么区别吗?无论如何,我更改了它并得到了相同的结果。您可能需要一个函数调用来等待池中的所有线程完成。不是一个vb程序员,我不知道API。三次。Join等待所有数据,所以这不应该是一个问题。将Option Strict放在源代码的顶部。修复代码片段中的错误。
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