多个数据表上的多线程
Multithreading on multiple datatables
TL;DR:为什么单线程应用程序 运行 执行此代码需要 80077 毫秒,而多线程应用程序需要 3 倍多的时间?
有点冗长的问题,可能会导致比我发现的更简单的解决方案。
我正在尝试根据硬编码的变量将一个数据table 分成 x
数量的数据table。这不是问题所在,尽管如果有人有比我更干净的解决方案,我将非常感谢在这方面的帮助。
我的问题是因为即使我生成了 x
数量的 BackgroundWorker
,我仍然得到的结果表明破坏主要 table 成多个 tables.
这背后的想法很简单 - 我们有一个应用程序只能 运行 一定数量的并发连接,比方说 10
并发连接。我希望能够获得初始数据 table 比方说 150,000
行,我知道对于 10
连接我也可以制作 10
数据table 每 15,000
行,然后单独处理每个 table,而不是用一个数据 table 推送 150,000
,全部在一个连接下。
到目前为止,这就是我想出的
Private Sub CheckJobcodesPendingUpdate()
Jobcode_AlreadyTried = New List(Of Integer)
Dim sw = Stopwatch.StartNew()
RTB.AppendText("I'm starting..." & vbCrLf)
Dim Jobcodes As DataTable = SQL.SQLdataTable("SELECT [Jobcode] FROM [database].[schema].[Jobcodes]")
sw.Stop
RTB.AppendText("Took " & sw.ElapsedMilliseconds & "ms to retrieve " & Jobcodes.Rows.Count & " rows." & vbCrLf)
Application.DoEvents
sw = Stopwatch.StartNew()
Dim ds As New DataSet
Dim dt As Datatable
Dim tableSeperator as Integer = Jobcodes.Rows.Count / 10 'The amount of connections we can have simultaneously.
Dim tableCount As Integer = 0
tableCount = Math.Ceiling(JobcodesEPC10.Rows.Count / tableSeperator)
Do Until tableCount = 0
dt = (From t In Jobcodes Order By t.Item("Jobcode") Ascending Select t).Take(tableSeperator).CopyToDataTable
For each row As DataRow In dt.Rows
Jobcodes.Rows.Remove(Jobcodes.AsEnumerable.First(Function(r) r.Item("Jobcode") = row.Item("Jobcode")))
Next
ds.Tables.Add(dt)
tableCount -= 1
Loop
sw.Stop
RTB.AppendText(vbCrLf & "Took " & sw.ElapsedMilliseconds & "ms to create all " & ds.Tables.Count & " tables.")
For each table As DataTable In ds.Tables
Dim WorkerJobcodes As New BackgroundWorker
AddHandler WorkerJobcodes.DoWork, AddressOf Async_Project
AddHandler WorkerJobcodes.RunWorkerCompleted, AddressOf WorkCompleted
WorkerJobcodes.RunWorkerAsync(table)
Next
End Sub
我不喜欢丢弃代码块并询问 'solve this'。这是调用的主要方法,BackgroundWorker
只是将每一行处理到系统中。
一切正常,但是当我使用 10
单独的 BackgroundWorker's
计时时,它花费了 262,597 毫秒;而在单个主线程上,它花费了 80,007 毫秒。
我是否误解了 BackgroundWorker
的概念,因此影响了我的表现?还是我用错了 tool/incorrectly?
提前致谢。
当您执行 CPU 绑定操作时,将这样的工作推送到线程很有用,但当您执行 IO 时,就会产生资源冲突,导致整个过程变慢。当您使用多线程时,您的硬盘会同时尝试访问驱动器的不同部分。当您只使用一个时,它可以按顺序自由读取数据,从而避免所有的查找延迟。
TL;DR:为什么单线程应用程序 运行 执行此代码需要 80077 毫秒,而多线程应用程序需要 3 倍多的时间?
有点冗长的问题,可能会导致比我发现的更简单的解决方案。
我正在尝试根据硬编码的变量将一个数据table 分成 x
数量的数据table。这不是问题所在,尽管如果有人有比我更干净的解决方案,我将非常感谢在这方面的帮助。
我的问题是因为即使我生成了 x
数量的 BackgroundWorker
,我仍然得到的结果表明破坏主要 table 成多个 tables.
这背后的想法很简单 - 我们有一个应用程序只能 运行 一定数量的并发连接,比方说 10
并发连接。我希望能够获得初始数据 table 比方说 150,000
行,我知道对于 10
连接我也可以制作 10
数据table 每 15,000
行,然后单独处理每个 table,而不是用一个数据 table 推送 150,000
,全部在一个连接下。
到目前为止,这就是我想出的
Private Sub CheckJobcodesPendingUpdate()
Jobcode_AlreadyTried = New List(Of Integer)
Dim sw = Stopwatch.StartNew()
RTB.AppendText("I'm starting..." & vbCrLf)
Dim Jobcodes As DataTable = SQL.SQLdataTable("SELECT [Jobcode] FROM [database].[schema].[Jobcodes]")
sw.Stop
RTB.AppendText("Took " & sw.ElapsedMilliseconds & "ms to retrieve " & Jobcodes.Rows.Count & " rows." & vbCrLf)
Application.DoEvents
sw = Stopwatch.StartNew()
Dim ds As New DataSet
Dim dt As Datatable
Dim tableSeperator as Integer = Jobcodes.Rows.Count / 10 'The amount of connections we can have simultaneously.
Dim tableCount As Integer = 0
tableCount = Math.Ceiling(JobcodesEPC10.Rows.Count / tableSeperator)
Do Until tableCount = 0
dt = (From t In Jobcodes Order By t.Item("Jobcode") Ascending Select t).Take(tableSeperator).CopyToDataTable
For each row As DataRow In dt.Rows
Jobcodes.Rows.Remove(Jobcodes.AsEnumerable.First(Function(r) r.Item("Jobcode") = row.Item("Jobcode")))
Next
ds.Tables.Add(dt)
tableCount -= 1
Loop
sw.Stop
RTB.AppendText(vbCrLf & "Took " & sw.ElapsedMilliseconds & "ms to create all " & ds.Tables.Count & " tables.")
For each table As DataTable In ds.Tables
Dim WorkerJobcodes As New BackgroundWorker
AddHandler WorkerJobcodes.DoWork, AddressOf Async_Project
AddHandler WorkerJobcodes.RunWorkerCompleted, AddressOf WorkCompleted
WorkerJobcodes.RunWorkerAsync(table)
Next
End Sub
我不喜欢丢弃代码块并询问 'solve this'。这是调用的主要方法,BackgroundWorker
只是将每一行处理到系统中。
一切正常,但是当我使用 10
单独的 BackgroundWorker's
计时时,它花费了 262,597 毫秒;而在单个主线程上,它花费了 80,007 毫秒。
我是否误解了 BackgroundWorker
的概念,因此影响了我的表现?还是我用错了 tool/incorrectly?
提前致谢。
当您执行 CPU 绑定操作时,将这样的工作推送到线程很有用,但当您执行 IO 时,就会产生资源冲突,导致整个过程变慢。当您使用多线程时,您的硬盘会同时尝试访问驱动器的不同部分。当您只使用一个时,它可以按顺序自由读取数据,从而避免所有的查找延迟。