询问者
DataTable Rows.Add 在多线程性能严重下降

问题
-
因需要读大量数据到 DataTable 再用 Linq 进行多线程并发计算 但发现 ImportRow()与DataTable.Rows.Add() 都会导致性能下降
'8核心的CPU(没开HT),32G内存
'当n=1 用1个线程时,CPU占用率 13%
'当n=2 用2个线程时,CPU占用率 20%
'当n=4 用4个线程时,CPU占用率 30%
'当n=8 用8个线程时,CPU占用率 45%
'估计是dt.Rows.Add有BUG 出现等待时间,导致CPU不能用尽
'若把n=8 循环里改成 x= 10^10 CPU占用率 100%具体多线程代码如下(完整代码,可直接调试):
Imports System.Runtime.InteropServices Imports System.ComponentModel Imports System.Threading Public Class Form1 Dim th(100) As Thread Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load System.Net.ServicePointManager.DefaultConnectionLimit = 512 System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False Thread.CurrentThread.Priority = ThreadPriority.Highest Dim i As Integer Dim n As Integer = 8 '8线程 For i = 1 To n th(i) = New Thread(AddressOf dowork) th(i).IsBackground = True th(i).Start() Next '=================================================== '8核心的CPU(没开HT),32G内存 '当n=1 用1个线程时,CPU占用率 13% '当n=2 用2个线程时,CPU占用率 20% '当n=4 用4个线程时,CPU占用率 30% '当n=8 用8个线程时,CPU占用率 45% '估计是dt.Rows.Add有BUG 出现等待时间,导致CPU不能用尽 '若把n=8 循环里改成 x= 10^10 CPU占用率 100% End Sub Sub dowork() Dim dt As New DataTable dt.Columns.Add("id", GetType(Integer)) dt.Columns.Add("c1", GetType(String)) dt.Columns.Add("c2", GetType(String)) dt.Columns.Add("c3", GetType(String)) dt.Columns.Add("c4", GetType(String)) Dim x As Decimal = 0 While True '循环 For i = 0 To 10000 '这个会性能下降,可能有等待,CPU不能用尽 dt.Rows.Add(i, "1", "2", "3", "4") Next dt.Clear() ' x = 10 ^ 10 End While End Sub End Class
全部回复
-
你好,
我建议你使用task 来做,这个通过线程池来管理的。
Dim t As Task = Task.Run(Sub() Dim dt As New DataTable dt.Columns.Add("id", GetType(Integer)) dt.Columns.Add("c1", GetType(String)) dt.Columns.Add("c2", GetType(String)) dt.Columns.Add("c3", GetType(String)) dt.Columns.Add("c4", GetType(String)) Dim x As Decimal = 0 While True '循环 For i = 0 To 10000 '这个会性能下降,可能有等待,CPU不能用尽 dt.Rows.Add(i, "1", "2", "3", "4") Next dt.Clear() MessageBox.Show("OK") ' x = 10 ^ 10 End While End Sub)
Best regards,
Zhanglong
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.