【发布时间】:2014-05-23 08:15:10
【问题描述】:
我正在使用 Xamarin 开发 iOS 应用。其中一项功能是以 hls 格式下载视频,这意味着每个视频可以有 100 到 1000 个块可供下载。所以我需要做 100 到 1000 个 http 请求。这是可行的,但下载时应用程序非常慢,我使用“仪器”进行了性能测试,CPU 为 80%,完成后又回到 0%-1%。这是在 ipad 上测试,不是在模拟器上。
public async Task CreateDownloadTask (string path){
var response = await _httpClient.GetAsync (GetUrl(path),
HttpCompletionOption.ResponseHeadersRead);
if (!response.IsSuccessStatusCode)
{
Debug.WriteLine ("Error: " + path);
RaiseFault(new RpcFault("Error: Unable to download video", -1));
}
else
{
var totalBytes = response.Content.Headers.ContentLength.HasValue
? response.Content.Headers.ContentLength.Value : -1L;
using (var stream = await response.Content.ReadAsStreamAsync ())
{
var isMoreToRead = true;
var data = new byte[totalBytes];
do
{
_cancelSource.Token.ThrowIfCancellationRequested ();
var buffer = new byte[4096];
int read = stream.ReadAsync(buffer,
0,
buffer.Length,
_cancelSource.Token).Result;
if (read == 0)
isMoreToRead = false;
else {
buffer.ToList ().CopyTo (0, data, receivedBytes, read);
receivedBytes += read;
HlsVideo.TotalReceived += read;
}
} while(isMoreToRead);
var fullPath = GetFullFilePath (path);
_fileStore.WriteFile (fullPath, data);
}
}
在执行多个 http 请求时如何提高性能?
【问题讨论】:
-
当您在缓冲区上调用
ToList()时?首先,这引入了不必要的复制。为什么要在while循环的每次迭代中创建一个新缓冲区?只需在循环之前创建它一次,这样您就可以继续重用同一个缓冲区。事实上,你为什么有buffer?您已经有效地获得了一个缓冲区 -data。直接阅读:int read = stream.ReadAsync(data, receivedBytes, totalBytes - receivedBytes, _cancelSource.Token).Result; -
你是对的!我删除了缓冲区,它似乎工作得更好。它减少了大约 20% 的 CPU 使用量!滚动项目列表时仍然不流畅,因此欢迎提供更多提示。谢谢!
-
您是否有任何理由使用同步调用
WriteFile?这也可能让它变得生涩...... -
太棒了!好多了,我现在异步调用 writeFile,它提高了性能!谢谢
-
好的 - 会写下来作为答案。
标签: c# ios http xamarin httprequest