I am trying to get progress of an api along with the response. ResponseHeadersRead
works fine to get the progress but I can't figure out why it doesn't return the response.
Download part
public async Task StartDownload()
{
_httpClient = new HttpClient { Timeout = TimeSpan.FromDays(1), };
using (var response = await _httpClient.GetAsync(_downloadUrl, HttpCompletionOption.ResponseHeadersRead))
{
await DownloadFileFromHttpResponseMessage(response);
string strResp = await response.Content.ReadAsStringAsync();
Debug.WriteLine(strResp); // Doesn't print anything
}
}
Reading Stream part
private async Task DownloadFileFromHttpResponseMessage(HttpResponseMessage response)
{
response.EnsureSuccessStatusCode();
var totalBytes = response.Content.Headers.ContentLength;
using (var contentStream = await response.Content.ReadAsStreamAsync())
{
await ProcessContentStream(totalBytes, contentStream);
}
}
The code is actually from another answer.
I am just not getting the response. If I use ResponseContentRead
I get response but it defeats the purpose of progress.
EDIT
ProcessContentStream code - This part read the response as it comes bit by bit and posts the progress in TriggerProgressChanged
private async Task ProcessContentStream(long? totalDownloadSize, Stream contentStream)
{
var totalBytesRead = 0L;
var readCount = 0L;
var buffer = new byte[8192];
var isMoreToRead = true;
using (var fileStream = new FileStream(DestinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
do
{
var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
isMoreToRead = false;
//TriggerProgressChanged(totalDownloadSize, totalBytesRead);
continue;
}
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
readCount += 1;
if (readCount % 100 == 0)
{
//TriggerProgressChanged(totalDownloadSize, totalBytesRead);
}
}
while (isMoreToRead);
}
}
Post the progress
private void TriggerProgressChanged(long? totalDownloadSize, long totalBytesRead)
{
if (ProgressChanged == null)
return;
double? progressPercentage = null;
if (totalDownloadSize.HasValue)
progressPercentage = Math.Round((double)totalBytesRead / totalDownloadSize.Value * 100, 2);
ProgressChanged(totalDownloadSize, totalBytesRead, progressPercentage);
}
ProgressChanged
is a delegate method.