如何从Httpclient ReadAsStreamAsync正确计算下载速度?

时间:2018-04-28 07:54:15

标签: c# .net httpclient download-speed

如何从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();
        }
    }
}

下载10mb文件的结果 result (can't add photo yet)

0 个答案:

没有答案