我想在复制大量文件(也是大文件)时获得准确的传输速率和剩余时间。这应该通过主进度条和定义的速度和剩余时间标签来可视化。
在例程开始时,后台工作人员遍历给定目录并构建具有源和目标路径的字典。
在此处找到的机制:计算文件复制的剩余时间。(史蒂文·利肯斯的回答)
问题是,永远不会达到 100% 的进度,它在某个时候以 96%-98% 完成,但从未达到 100%。使用不同的方法计算(递归)目录计算的总字节数可能有所不同。
下一点是,显示的传输速率甚至是正确的,如果它乘以 10 .... 所以我的 ssd 机器显示的传输速率显示为 30 MB/s,更像是 300 MB/s。显示的速率肯定是错误的。
所以这里有2个问题:1.)错误的进度计算2.)错误的传输率计算(速度还可以)
谁能指出为什么?
private void CopyFileList(DoWorkEventArgs eWorker)
{
if (fileWorker.CancellationPending)
{
eWorker.Cancel = true;
}
else
{
var totalBytes = GetTotalBytes();
var currentBytesTransferred = 0L;
var totalBytesTransferred = 0L;
var snapshots = new Queue<long>(30);
var timer = new System.Timers.Timer(100D);
foreach (var file in FilesToCopy)
{
var sourcePath = file.Key;
var destinationPath = file.Value;
var sourceFile = new FileInfo(sourcePath);
//var fileSize = sourceFile.Length;
timer.Elapsed += (sender, e) =>
{
if (fileWorker.CancellationPending)
{
eWorker.Cancel = true;
}
else
{
// Remember only the last 30 snapshots; discard older snapshots
if (snapshots.Count == 30)
{
snapshots.Dequeue();
}
snapshots.Enqueue(Interlocked.Exchange(ref currentBytesTransferred, 0L));
var averageSpeed = snapshots.Average();
var bytesLeft = totalBytes - totalBytesTransferred;
var speedText = string.Format("{0:#} MB/s", averageSpeed / (1024 * 1024));
var timeLeftText = string.Empty;
if (averageSpeed > 0)
{
var timeLeft = TimeSpan.FromSeconds(bytesLeft / averageSpeed);
var timeLeftRounded = TimeSpan.FromSeconds(Math.Round(timeLeft.TotalSeconds));
timeLeftText = string.Format("{0}", timeLeftRounded);
}
else
{
timeLeftText = ("-infinite-");
}
Console.WriteLine(speedText);
Console.WriteLine("Time Left: " + timeLeftText);
fileWorker.ReportProgress((currentBytesTransferred / maximum) * 100));
}
};
using (var inputStream = sourceFile.OpenRead())
using (var outputStream = File.OpenWrite(destinationPath))
{
timer.Start();
var buffer = new byte[4096 * 8];
var numBytes = default(int);
var numBytesMax = buffer.Length;
var timeout = TimeSpan.FromMinutes(10D);
do
{
var mre = new ManualResetEvent(false);
inputStream.BeginRead(buffer, 0, numBytesMax, asyncReadResult =>
{
numBytes = inputStream.EndRead(asyncReadResult);
outputStream.BeginWrite(buffer, 0, numBytes, asyncWriteResult =>
{
if (fileWorker.CancellationPending)
{
eWorker.Cancel = true;
return;
}
else
{
outputStream.EndWrite(asyncWriteResult);
currentBytesTransferred = Interlocked.Add(ref currentBytesTransferred, numBytes);
Results.SizeProgressed = totalBytesTransferred;
totalBytesTransferred = Interlocked.Add(ref totalBytesTransferred, numBytes);
mre.Set();
}
}, null);
}, null);
mre.WaitOne(timeout);
} while (numBytes != 0);
timer.Stop();
}
}
}
}
一个例子:
将目录(21 个目录,228 个文件,总计:326MB)复制到 NAS 需要:12.4434796 秒,据报道平均速度为 2-3 MB/秒。但复制速度快了近10倍。