如何从Httpclient ReadAsStreamAsync正确计算下载速度?我试图通过减去TotalBytesRead - OldTotalBytesRead来获得旧的下载速度,它按预期工作,但问题在于经过的时间,我怎么能这样做它将精确计算经过的时间等于1000ms,在下面的代码中,速度计算运行>经过的时间,速度有时是不准确的,使第一个值太大,然后秒数很小或反之亦然。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleDownloadApp
{
class Program
{
[DllImport("Shlwapi.dll", CharSet = CharSet.Auto)]
private static extern long StrFormatByteSize(
long fileSize,
[MarshalAs(UnmanagedType.LPTStr)] StringBuilder buffer,
int bufferSize);
static HttpClient _httpClient = new HttpClient();
static long ContentLength = 0;
static long TotalBytesRead = 0;
static long OldTotalBytesRead = 0;
static void Main(string[] args)
{
string url = "http://ipv4.download.thinkbroadband.com/10MB.zip";
string savePath = "10MB.zip";
Task.Run(() => Download(url, savePath)).Wait();
}
static async Task Download(string url, string saveAs)
{
using (HttpResponseMessage response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
ContentLength = response.Content.Headers.ContentLength ?? 0;
byte[] buffer = new byte[1024];
Stopwatch st = new Stopwatch();
st.Start();
using (Stream contentStream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(saveAs, FileMode.Create, FileAccess.Write, FileShare.None, buffer.Length, true))
{
while(true)
{
var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
if(bytesRead == 0)
{
Console.WriteLine("Download complete.");
break;
}
await fileStream.WriteAsync(buffer, 0, bytesRead);
TotalBytesRead += bytesRead;
var elapsedTime = st.ElapsedMilliseconds;
if (elapsedTime >= 1000)
{
st.Reset();
st.Start();
long bytesChanged = TotalBytesRead - OldTotalBytesRead;
OldTotalBytesRead = TotalBytesRead;
Console.WriteLine("Elapsed time: {0} || Download speed: {1} || {2}/{3}",
elapsedTime,
StrFormatByteSize(bytesChanged / elapsedTime),
StrFormatByteSize(TotalBytesRead),
StrFormatByteSize(ContentLength));
}
}
}
}
}
/// <summary>
/// Converts a numeric value into a string that represents the number expressed as a size value in
/// bytes, kilobytes, megabytes, or gigabytes, depending on the size.
/// </summary>
/// <param name="filelength">The numeric value to be converted.</param>
/// <returns>the converted string</returns>
public static string StrFormatByteSize(long filesize)
{
StringBuilder sb = new StringBuilder(11);
StrFormatByteSize(filesize, sb, sb.Capacity);
return sb.ToString();
}
}
}