如何在使用多个线程VB.net时降低CPU使用率?

时间:2015-01-23 02:09:27

标签: vb.net multithreading

我正在使用vb.net,.NetFramework 2.0。

我的应用程序从谷歌获得实时股票价格,每10秒钟更新数据库中的股票。

我为多线程获取此代码。当应用程序开始更新数据库中的库存(大约200个库存)时,更新最多需要3秒,但它会将CPU使用率从10%增加到70%或80%。

在不将CPU增加到高水平的情况下更新数据库的最佳方法是什么?

我观察到所有线程同时工作。如何使每个线程等到第二个结束?

这是我的代码。问题出在函数updateThreaded2()。

我需要快速帮助。感谢

Public Function Update2(ByVal l As SortableBindingList(Of NewStockList)) As Long
    res = 0
    UThread = New System.Threading.Thread(AddressOf UpdateThreaded2)
    If Me.URunning = True Then
    Else
        Try
            Me.URunning = True
            Interlocked.Exchange(Me.UCount, 0)  'threadsafe method of assigning static value
            Interlocked.Exchange(Me.UDone, 0)   'threadsafe method of assigning static value
            UThread.Priority = Threading.ThreadPriority.BelowNormal
            UThread.IsBackground = True
            UThread.Start(l)
            Return 0
        Catch ex As Exception
        End Try
    End If
End Function




Private Sub UpdateThreaded2(ByVal l As SortableBindingList(Of NewStockList))

    Dim i As Integer = 0
    Dim threadcount As Integer = Math.Min(Me.MaxThreads, Me.Stocks.Count)
    Dim threads(threadcount - 1) As SUTC
    Try
        While i < Me.Stocks.Count
            For j As Integer = 0 To threadcount - 1
                If threads(j) Is Nothing Then
                    If i < Me.Stocks.Count Then
                        threads(j) = New SUTC(Me.Stocks(i), Me.DefaultService, AdjustSplits, Use20Minutes, l)
                        threads(j).Thread.Priority = Threading.ThreadPriority.BelowNormal
                        threads(j).Thread.IsBackground = True
                        threads(j).Thread.Start()

                        i += 1
                    End If
                ElseIf threads(j).UpdateState = 0 Then
                    If i < Me.Stocks.Count Then
                        SecUpd(j) = Me.Stocks(i).symbol
                        threads(j) = New SUTC(Me.Stocks(i), Me.DefaultService, AdjustSplits, Use20Minutes, l)
                        threads(j).Thread.Priority = Threading.ThreadPriority.BelowNormal
                        threads(j).Thread.IsBackground = True
                        threads(j).Thread.Start()
                        i += 1

                    End If
                End If
            Next

            Dim running As Boolean = True
            While running
                For j As Integer = 0 To threadcount - 1
                    If threads(j).UpdateState = 0 Then
                        Thread.Sleep(10)
                        running = False
                        SecUpd(j) = ""
                        Interlocked.Increment(UDone)  'threadsafe method of incrementing a variable by 1
                        Interlocked.Exchange(UCount, UCount + threads(j).UpdateCount)   'Threadsafe method for assigning a value
                    End If
                Next
            End While
        End While

        Dim pending As Integer = threadcount
        Dim tempcount As Integer = 0
        Dim oldcount As Integer = UCount

        While pending > 0
            pending = threadcount
            tempcount = 0
            For i = 0 To threadcount - 1
                If threads(i).UpdateState = 0 Then
                    SecUpd(i) = ""
                    pending -= 1
                    tempcount += threads(i).UpdateCount
                    Thread.Sleep(10)
                End If
            Next
            Interlocked.Exchange(UDone, Me.Stocks.Count - pending)  'Threadsafe method for assigning a value
            Interlocked.Exchange(UCount, oldcount + tempcount)      'Threadsafe method for assigning a value
        End While

        Me.URunning = False
    Catch ex As System.Threading.ThreadAbortException   'handle abort correctly
        Dim pending As Integer = threadcount
        Dim tempcount As Integer = 0
        Dim oldcount As Integer = UCount
        While pending > 0
            pending = threadcount
            tempcount = 0
            For i = 0 To threadcount - 1
                If threads(i).UpdateState = 0 Then
                    SecUpd(i) = ""
                    pending -= 1
                    tempcount += threads(i).UpdateCount
                End If
            Next
            Interlocked.Exchange(UDone, Me.Stocks.Count - pending)  'Threadsafe method for assigning a value
            Interlocked.Exchange(UCount, oldcount + tempcount)      'Threadsafe method for assigning a value
        End While
    End Try

End Sub

1 个答案:

答案 0 :(得分:0)

这是非常简化的,但是线程本质上会同时运行(如果可能的话,并且在某种程度上取决于操作系统的奇思妙想)。如果你想减少同时进行,请使用更少的线程。在您的情况下,由于您希望按顺序完成作业,因此您实际上只需要一个线程。

如上所述,最好的方法是创建一个在单个后台线程上运行的后台工作程序。通常有一个队列,您可以从前台线程以线程安全的方式提交作业。线程proc通常在无限循环中运行,处理队列中的每个作业,并且在没有作业时进入休眠状态等待新作业。