我有一个程序从dbase数据库中提取大量数据,执行一些简单的循环和计算,然后绘制结果图。我注意到完成此操作所需的时间似乎随机变化。我在代码中实现了一个计时器,它只是告诉我什么例程导致了慢速。奇怪的是,它从开始到结束需要大约5秒钟或大约25秒,从不介于两者之间。根据计时器,时间延迟(发生时)是填充数据集时。请注意,该过程总共重复5次,因此实际上每次填充每个数据集需要大约0.5秒或大约4.5秒。
注意事项: 1)dbase数据库存储在网络上的计算机上 2)数据集填充的数据量变化很大,对速度没有影响。 (例如,上次发生这种情况时,填充数据集的第一个循环有134条记录,仅用于填充数据集的4.524s,5循环通过523条记录并获得4.756s。
有关导致这种情况或更好的原因以及如何解决问题的任何想法?
这就是我定时的代码:
Form1.pCodeTimer.StartProc("DBFillds" & Cnt)
RecordCount = DBda.Fill(DBds, "DB_Data")
Form1.pCodeTimer.EndProc("DBFillds" & Cnt)
第一行和最后一行简单启动和停止计时器。
编辑: 这是“计时器”的代码我很好奇为什么这对于代码计时这么糟糕的方式,除非我通过称它为“计时器”误导所有人。
Public Class CodeTimer
Dim Processes As New List(Of MyProcess)
Dim CodeStart As Long
Public Sub StartProc(ProcName As String)
Dim Proc As MyProcess = New MyProcess(ProcName)
Processes.Add(Proc)
End Sub
Public Sub EndProc(ProcName As String)
Dim ProcMatches As New List(Of MyProcess)
ProcMatches = Processes.FindAll(Function(column) column.ProcName = ProcName)
If ProcMatches.Count > 1 Then
'MsgBox("More than one process found that matches the name '" & ProcName & "'.")
Else
ProcMatches(0).ProcEnd()
End If
End Sub
Public Sub StartTimer()
CodeStart = DateTime.Now.Ticks
End Sub
Public Sub EndTimer()
Dim strResult As String = ""
Dim TotalTime As TimeSpan = New TimeSpan(DateTime.Now.Ticks - CodeStart)
For i As Integer = 0 To Processes.Count - 1
strResult += Processes(i).ProcName & ": " & Processes(i).ElapsedTime.Seconds.ToString & "." & Processes(i).ElapsedTime.Milliseconds.ToString & "s" & vbCrLf
If Processes(i).ProcDesc <> "" Then
strResult += Processes(i).ProcDesc & vbCrLf
End If
Next
strResult += "Total Timer Run Time: " & TotalTime.Seconds & "." & TotalTime.Milliseconds.ToString & "s"
If TotalTime.Seconds > 5 Then
MsgBox(strResult)
End If
End Sub
Public Sub AddDesc(ProcName As String, newProcDesc As String)
Dim ProcMatches As New List(Of MyProcess)
ProcMatches = Processes.FindAll(Function(column) column.ProcName = ProcName)
If ProcMatches.Count > 1 Then
'MsgBox("More than one process found that matches the name '" & ProcName & "'.")
Else
ProcMatches(0).ProcDesc = newProcDesc
End If
End Sub
End Class
它使用的Process类:
Public Class MyProcess
Public ProcName As String
Public ProcDesc As String
Public ElapsedTime As TimeSpan
Public StartTime As Long
Public EndTime As Long
Public Sub ProcEnd()
EndTime = DateTime.Now.Ticks
ElapsedTime = New TimeSpan(EndTime - StartTime)
End Sub
Public Sub New(newProcName As String, Optional newProcDesc As String = "")
ProcName = newProcName
StartTime = DateTime.Now.Ticks
If newProcDesc <> "" Then
ProcDesc = newProcDesc
End If
End Sub
End Class
这是运行查询时的代码片段:
pCodeTimer.StartProc("QueryYr" & i)
SQL = "SELECT J_ASALE as ActSale, J_PSALE as ProjSale, J_ENTDATE as JobDate, C_CUSTOMER as CustNum FROM JOB WHERE " & strClassFilter & "J_ENTDATE >= #" & fisYrStart & "# AND J_ENTDATE < #" & fisYrEnd & "#"
DB.RunQuery(SQL)
pCodeTimer.EndProc("QueryYr" & i)
pCodeTimer.StartProc("LoadYr" & i)
fyrSalesData.LoadData(DB.DBds.Tables(0), isQuotedJob)
pCodeTimer.EndProc("LoadYr" & i)
最后,DB.Runquery等中的“DB”是此DBConnection类的实例
Imports System.Data
Imports System.Data.OleDb
Public Class DBConnection
'DATABASE CONNECTION
Private DBcon As New OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source=Z:\DATA\DATABASE\;extended properties=dbase Iv;")
Private DBcmd As OleDbCommand
'DB Data
Public DBda As OleDbDataAdapter
Public DBds As DataSet
'QUERY PARAMETERS
Public Params As New List(Of OleDbParameter)
'QUERY STATS
Public RecordCount As Integer
Public Exception As String
Dim Cnt As Integer = 0
Public Sub RunQuery(Query As String)
Cnt += 1
Try
Form1.pCodeTimer.StartProc("OpenDBcon" & Cnt)
DBcon.Open()
Form1.pCodeTimer.EndProc("OpenDBcon" & Cnt)
'CREATE SQL COMMAND
Form1.pCodeTimer.StartProc("DBCreateCmd" & Cnt)
DBcmd = New OleDbCommand(Query, DBcon)
Form1.pCodeTimer.EndProc("DBCreateCmd" & Cnt)
'LOAD PARAMETERS INTO OLEDB COMMAND
Params.ForEach(Sub(x) DBcmd.Parameters.Add(x))
'CLEAR PARAMETERS LIST
Params.Clear()
'EXECUTE COMMAND AND FILL DATASET
DBds = New DataSet
DBds.Clear()
Form1.pCodeTimer.StartProc("DBExecuteCmd" & Cnt)
DBda = New OleDbDataAdapter(DBcmd)
Form1.pCodeTimer.EndProc("DBExecuteCmd" & Cnt)
Form1.pCodeTimer.StartProc("DBFillds" & Cnt)
RecordCount = DBda.Fill(DBds, "DB_Data")
Form1.pCodeTimer.EndProc("DBFillds" & Cnt)
Form1.pCodeTimer.AddDesc("DBFillds" & Cnt, "Record Count: " & RecordCount)
DBcon.Close()
Catch ex As Exception
'CAPTURE ERRORS
MsgBox(ex.Message)
Dim i As Integer = 1
End Try
'MAKE SURE CONNECTION IS CLOSED
If DBcon.State = ConnectionState.Open Then DBcon.Close()
End Sub
Public Sub AddParam(Name As String, Value As Object)
Dim NewParam As New OleDbParameter(Name, Value)
Params.Add(NewParam)
End Sub
End Class
这是定时器日志的图片(这是一个“快速”加载,“DBFillds#:”是易失性部分。
我很清楚我可能没有最优雅的编码技术,但它有效。 :)