Improve download performance.
This commit is contained in:
parent
3982edd0f1
commit
3aebc7c885
@ -61,9 +61,6 @@ namespace AaxDecrypter
|
|||||||
|
|
||||||
#region Constants
|
#region Constants
|
||||||
|
|
||||||
//Size of each range request. Android app uses 64MB chunks.
|
|
||||||
private const int RANGE_REQUEST_SZ = 64 * 1024 * 1024;
|
|
||||||
|
|
||||||
//Download memory buffer size
|
//Download memory buffer size
|
||||||
private const int DOWNLOAD_BUFF_SZ = 8 * 1024;
|
private const int DOWNLOAD_BUFF_SZ = 8 * 1024;
|
||||||
|
|
||||||
@ -161,7 +158,7 @@ namespace AaxDecrypter
|
|||||||
|
|
||||||
//Initiate connection with the first request block and
|
//Initiate connection with the first request block and
|
||||||
//get the total content length before returning.
|
//get the total content length before returning.
|
||||||
using var client = new HttpClient();
|
var client = new HttpClient();
|
||||||
var response = await RequestNextByteRangeAsync(client);
|
var response = await RequestNextByteRangeAsync(client);
|
||||||
|
|
||||||
if (ContentLength != 0 && ContentLength != response.FileSize)
|
if (ContentLength != 0 && ContentLength != response.FileSize)
|
||||||
@ -170,38 +167,54 @@ namespace AaxDecrypter
|
|||||||
ContentLength = response.FileSize;
|
ContentLength = response.FileSize;
|
||||||
|
|
||||||
_downloadedPiece = new EventWaitHandle(false, EventResetMode.AutoReset);
|
_downloadedPiece = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||||
//Hand off the open request to the downloader to download and write data to file.
|
//Hand off the client and the open request to the downloader to download and write data to file.
|
||||||
DownloadTask = Task.Run(() => DownloadLoopInternal(response), _cancellationSource.Token);
|
DownloadTask = Task.Run(() => DownloadLoopInternal(client , response), _cancellationSource.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DownloadLoopInternal(BlockResponse initialResponse)
|
private async Task DownloadLoopInternal(HttpClient client, BlockResponse blockResponse)
|
||||||
{
|
{
|
||||||
await DownloadToFile(initialResponse);
|
|
||||||
initialResponse.Dispose();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var client = new HttpClient();
|
long startPosition = WritePosition;
|
||||||
|
|
||||||
while (WritePosition < ContentLength && !IsCancelled)
|
while (WritePosition < ContentLength && !IsCancelled)
|
||||||
{
|
{
|
||||||
using var response = await RequestNextByteRangeAsync(client);
|
try
|
||||||
await DownloadToFile(response);
|
{
|
||||||
|
await DownloadToFile(blockResponse);
|
||||||
|
}
|
||||||
|
catch (HttpIOException e)
|
||||||
|
when (e.HttpRequestError is HttpRequestError.ResponseEnded
|
||||||
|
&& WritePosition < ContentLength && !IsCancelled)
|
||||||
|
{
|
||||||
|
//the download made *some* progress since the last attempt.
|
||||||
|
//Try again to complete the download from where it left off.
|
||||||
|
//Make sure to rewind file to last flush position.
|
||||||
|
_writeFile.Position = startPosition = WritePosition;
|
||||||
|
blockResponse.Dispose();
|
||||||
|
blockResponse = await RequestNextByteRangeAsync(client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_writeFile.Close();
|
_writeFile.Dispose();
|
||||||
|
blockResponse.Dispose();
|
||||||
|
client.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<BlockResponse> RequestNextByteRangeAsync(HttpClient client)
|
private async Task<BlockResponse> RequestNextByteRangeAsync(HttpClient client)
|
||||||
{
|
{
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, Uri);
|
using var request = new HttpRequestMessage(HttpMethod.Get, Uri);
|
||||||
|
|
||||||
|
//Just in case it snuck in the saved json (Issue #1232)
|
||||||
|
RequestHeaders.Remove("Range");
|
||||||
|
|
||||||
foreach (var header in RequestHeaders)
|
foreach (var header in RequestHeaders)
|
||||||
request.Headers.Add(header.Key, header.Value);
|
request.Headers.Add(header.Key, header.Value);
|
||||||
|
|
||||||
request.Headers.Add("Range", $"bytes={WritePosition}-{WritePosition + RANGE_REQUEST_SZ - 1}");
|
request.Headers.Add("Range", $"bytes={WritePosition}-");
|
||||||
|
|
||||||
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancellationSource.Token);
|
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancellationSource.Token);
|
||||||
|
|
||||||
@ -226,7 +239,7 @@ namespace AaxDecrypter
|
|||||||
private async Task DownloadToFile(BlockResponse block)
|
private async Task DownloadToFile(BlockResponse block)
|
||||||
{
|
{
|
||||||
var endPosition = WritePosition + block.BlockSize;
|
var endPosition = WritePosition + block.BlockSize;
|
||||||
var networkStream = await block.Response.Content.ReadAsStreamAsync(_cancellationSource.Token);
|
using var networkStream = await block.Response.Content.ReadAsStreamAsync(_cancellationSource.Token);
|
||||||
|
|
||||||
var downloadPosition = WritePosition;
|
var downloadPosition = WritePosition;
|
||||||
var nextFlush = downloadPosition + DATA_FLUSH_SZ;
|
var nextFlush = downloadPosition + DATA_FLUSH_SZ;
|
||||||
@ -286,7 +299,6 @@ namespace AaxDecrypter
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
networkStream.Close();
|
|
||||||
_downloadedPiece.Set();
|
_downloadedPiece.Set();
|
||||||
OnUpdate();
|
OnUpdate();
|
||||||
}
|
}
|
||||||
@ -359,7 +371,7 @@ namespace AaxDecrypter
|
|||||||
/// <param name="requiredPosition">The minimum required flushed data length in <see cref="SaveFilePath"/>.</param>
|
/// <param name="requiredPosition">The minimum required flushed data length in <see cref="SaveFilePath"/>.</param>
|
||||||
private void WaitToPosition(long requiredPosition)
|
private void WaitToPosition(long requiredPosition)
|
||||||
{
|
{
|
||||||
while (_readFile.Position < requiredPosition
|
while (WritePosition < requiredPosition
|
||||||
&& DownloadTask?.IsCompleted is false
|
&& DownloadTask?.IsCompleted is false
|
||||||
&& !IsCancelled)
|
&& !IsCancelled)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user