首页 > 解决方案 > 通过 ReadAsStreamAsync 限制 HttpClient 的下载速度

问题描述

我在下面有这个函数,它从我们的 API 下载一个多部分文件。我们的文件范围从 5MB 到 300MB。我想输入逻辑来计算它当前正在传输的下载速度,如果它高于可配置的限制,请将下载速度减慢到或低于限制。

我试过让线程休眠,但这会减慢它的速度。缓冲区是我可以更改的唯一可配置的东西,还是有其他一些 HttpClient 方法可以做到这一点?

var request = new HttpRequestMessage(HttpMethod.Get,
    string.Format("/api/device/DownloadFile/?fileID={0}", fileID));

using (HttpResponseMessage response = client.GetAsync(request.RequestUri, HttpCompletionOption.ResponseHeadersRead).Result)
{
    try
    {
        if (response.IsSuccessStatusCode)
        {
            Logging.LogDebug(string.Format("[DownloadFile] Starting download of '{0}'...", fileID));
            int downBuffer = 512;
            using (System.IO.Stream contentStream = await response.Content.ReadAsStreamAsync(), fileStream = new System.IO.FileStream(fileLocationTemp.FullName, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None, downBuffer, true))
            {
                var totalRead = 0L;
                var totalReads = 0L;
                var buffer = new byte[downBuffer];
                var isMoreToRead = true;

                do
                {
                    var read = await contentStream.ReadAsync(buffer, 0, buffer.Length);
                    if (read == 0)
                    {
                        isMoreToRead = false;
                    } else
                    {
                        await fileStream.WriteAsync(buffer, 0, read);

                        totalRead += read;
                        totalReads += 1;

                        if (totalReads % 2000 == 0)
                        {
                            Logging.LogDebug(string.Format("[DownloadFile] Total bytes downloaded so far: {0:n0}", totalRead));
                        }
                        
                        //I tested putting this in to slow it down.  It definitely slowed it down, but too much
                        //System.Threading.Thread.Sleep(2);
                    }
                }
                while (isMoreToRead);
            }

        } else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
        {
            Logging.LogDebug(string.Format("[DownloadFile] Failed to download file '{0}', not found on server.", fileID));
            deleteFilesOnFinal = true;
            return false;
        } else
        {
            Logging.LogDebug(string.Format("[DownloadFile] Failed to download file '{0}', status code '{1}'.", fileID, response.StatusCode.ToString()));
            deleteFilesOnFinal = true;
            return false;
        }
    }
    catch (Exception ex)
    {
        Logging.LogDebug(string.Format("[DownloadFile] Failed to download file '{0}'", fileID));
        Logging.LogError(ex);
        return false;
    }

}

标签: c#.net-coredotnet-httpclient

解决方案


推荐阅读