我正在使用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
答案 0 :(得分:0)
这是非常简化的,但是线程本质上会同时运行(如果可能的话,并且在某种程度上取决于操作系统的奇思妙想)。如果你想减少同时进行,请使用更少的线程。在您的情况下,由于您希望按顺序完成作业,因此您实际上只需要一个线程。
如上所述,最好的方法是创建一个在单个后台线程上运行的后台工作程序。通常有一个队列,您可以从前台线程以线程安全的方式提交作业。线程proc通常在无限循环中运行,处理队列中的每个作业,并且在没有作业时进入休眠状态等待新作业。