【发布时间】:2020-03-20 10:51:31
【问题描述】:
我正在尝试使用 multipartform-data 通过我的 API 上传 *.iso 文件并将它们流式传输到本地文件夹。 我使用了 Stream.CopyAsync(destinationStream) ,它运行缓慢,但还不错。但现在我需要报告进度。所以我使用了自定义 CopyTOAsync 并向其添加了进度报告。但是该方法非常慢(根本不可接受),即使与 Stream::CopyToASync 相比也是如此。
public async Task CopyToAsync(Stream source, Stream destination, long? contentLength, ICommandContext context, int bufferSize = 81920 )
{
var buffer = new byte[bufferSize];
int bytesRead;
long totalRead = 0;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await destination.WriteAsync(buffer, 0, bytesRead);
totalRead += bytesRead;
context.Report(CommandResources.RID_IMAGE_LOADIND, Math.Clamp((uint)((totalRead * 100) / contentLength), 3, 99));
}
_logger.Info($"Total read during upload : {totalRead}");
}
我尝试了什么: Stream::CopyToAsync 的默认缓冲区大小为 81920 字节,我先使用相同的值,然后尝试将缓冲区大小增加到 104857600 字节 - 没有区别。
您对如何提高自定义 CopyToAsync 的性能还有其他想法吗?
【问题讨论】:
-
那些文件是什么?您可以使用压缩流传输未压缩的文件。
-
传输一个 1GB 的文件需要多长时间?您是否将这些文件上传到远程服务器?还是一切都保留在您的本地网络上?
-
我不想告诉你,但你的方法一开始就有问题。想要更快的性能?不要发送 MULTIPARTFORM-DATA - 那里的编码使您的数据开始时大 30%,因为它必须是 ASCII 编码的。将它们作为二进制内容以 serate 请求(无形式)流式传输。在(获取上传网址)之前或作为标题发送必要的元数据 aeitehr。看看 Youtube 在他们的 SDK 中是如何做到的。
-
@ChristophLütjen 我怀疑
ArrayPool是否有助于考虑到有问题的代码不是在紧密循环中分配数组。
标签: c# asp.net-core stream multipartform-data large-files