我有问题正确估计一个现实的剩余时间'应用程序的副本应用程序。我使用Filestream
作为副本,因为要复制的文件从> 1MB到4GB不等。我在这里使用percentageTotal
来计算文件复制的当前位置:
'Loop through each file in the SourceDir
For Each ChildFile In SourceDir.GetFiles()
If (worker.CancellationPending = True) Then
e.Cancel = True
End If
'Calculate data being moved for eta to completion
Dim filetotalbytes As Double = ChildFile.Length
filetotalsofarcopied = filetotalbytes + filetotalsofarcopied
'Display file being copied
SetLabelText_ThreadSafe(Me.lblStatus, "Copying: " & line & "\" & ChildFile.Name & "")
'Do the copy
ChildFile.CopyTo(Path.Combine(DestDir.FullName, ChildFile.Name), True)
'Contruct Destination and Source Strings
deststring = DestDir.ToString & "\" & ChildFile.Name
Dim sourcedirstring As String
sourcedirstring = SourceDir.ToString & "\" & ChildFile.Name
Dim CopyStream As New FileStream(sourcedirstring, FileMode.Open, FileAccess.Read)
Dim NewStream As New FileStream(deststring, FileMode.Append)
Dim Buffer(4096) As Byte
Dim BytesRead As Integer
Dim len As Long = CopyStream.Length - 1
While CopyStream.Position < len
BytesRead = CopyStream.Read(Buffer, 0, Buffer.Length)
NewStream.Write(Buffer, 0, BytesRead)
percentageTotal = ((NewStream.Length + filetotalsofarcopied) / Overallsize * 100)
percentageTotal = Decimal.Round(percentageTotal)
' SetLabelText_ThreadSafe(Me.lblTotalProgress, "" & percentageTotal & "%")
End While
CopyStream.Dispose()
NewStream.Dispose()
我发现percentageTotal
的值经常跳跃而不是像我期望的那样以线性方式增加。谁能看到我在哪里错了?
此外,我无法完善secondsremaining
值的逻辑。它目前显示复制花费的天数,最初运行之前快速减少,但显然不是正确的剩余时间。
'Start process snippit
'Start Button Click config - starts the backgroundworker
Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Set start value - label22 is hidden on form1
Label22.Text = "0"
'Start timers
Timer3.Start()
Timer4.Start()
'Start background worker
BackgroundWorker1.WorkerSupportsCancellation = True
BackgroundWorker1.WorkerReportsProgress = True
BackgroundWorker1.RunWorkerAsync()
End Sub
UPDATED!并且表单末尾的Timer.Tick代码计算剩余时间:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
byteslastsecond = filetotalsofarcopied
End Sub
'Every tick of Timer4 calculates the time needed to complete the copy.
Private Sub Timer4_Tick(sender As Object, e As EventArgs) Handles Timer4.Tick
Dim time As Long = Label22.Text
If percentageTotal = 0 Then
SetLabelText_ThreadSafe(Me.lblEstTimeLeft, "Estimated Time Left (All Files): Estimating...")
Else
Dim secondsRemaining As Double = (Overallsize - filetotalsofarcopied) / (filetotalsofarcopied - byteslastsecond)
Dim ts As TimeSpan = TimeSpan.FromSeconds(secondsRemaining)
任何人都可以在剩下的时间内纠正我的逻辑吗?
答案 0 :(得分:1)
代码的问题在于,即使整个文件尚未复制,您也会将filetotalsofarcopied
增加整个文件大小。您应该在复制数据块时递增它。
所以删除它:
'Calculate data being moved for eta to completion
Dim filetotalbytes As Double = ChildFile.Length
filetotalsofarcopied = filetotalbytes + filetotalsofarcopied
并将其放入While
循环中:
BytesRead = CopyStream.Read(Buffer, 0, Buffer.Length)
NewStream.Write(Buffer, 0, BytesRead)
filetotalsofarcopied += BytesRead
percentageTotal = ((NewStream.Length + filetotalsofarcopied) / Overallsize * 100)
percentageTotal = Decimal.Round(percentageTotal)
这应该使时间估计工作正确,并显示百分比。
您还应删除此内容:
'Do the copy
ChildFile.CopyTo(Path.Combine(DestDir.FullName, ChildFile.Name), True)
因为你通过两次复制文件浪费时间和资源。
修改强>
实际上,我错过了一些错误。
此:
percentageTotal = ((NewStream.Length + filetotalsofarcopied) / Overallsize * 100)
应该是这样的:
percentageTotal = (filetotalsofarcopied / Overallsize * 100)
因为当前的写入字节数已经通过filetotalsofarcopied
变量添加到BytesRead
。