我正在使用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请求时,我该怎么做才能提高性能?
答案 0 :(得分:2)
目前的代码存在两个问题:
“异步写入数据”可能是一个更简单的修复,所以让我们看一下读取数据的低效率:
buffer
。我们不关心上一次迭代的数据,因此您可以在while
循环之前分配一次ToList
上致电buffer
,这将打印副本 - 然后您将其复制到data
您根本不需要buffer
!您可以直接将直接字节读入data
来代替两个分配和两个副本:
var data = new byte[totalBytes];
do {
_cancelSource.Token.ThrowIfCancellationRequested ();
int read = stream.ReadAsync(data, receivedBytes, data.Length - receivedBytes,
_cancelSource.Token).Result;
receivedBytes += read;
if (read == 0 || receivedBytes == data.Length)
isMoreToRead = false;
}
HlsVideo.TotalReceived += read;
} while(isMoreToRead);
// TODO: check that receivedBytes == data.Length!