c# - 通过 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;
}
}
解决方案
推荐阅读
- android - 用户登录时如何保护非消耗性应用内购买
- mysql - MySQL - 存储过程错误操作数应包含 1 列
- r - 具有多个条件的 IF 语句始终为真(嵌套在 while 循环中)
- python - 将 url_for 分配给变量并将其用作 render_template 中的参数,不起作用
- c# - 如何使用 C# 在 firebase 和 unity 之间引入和保存数据?
- mysql - MySql 连接字符串本地主机
- php - 有没有办法在 PHP 中每个月后增加一个数字
- c - 如何在 C 中的 for 循环中分配给变量?
- swift - Swift:无法以编程方式编辑自定义表格单元格的属性
- c# - 如何根据 c# 代码的更改刷新角度视图