So far here's my code:
async Task<bool> HttpDownloadAndUnzip(string requestUri, string directoryToUnzip)
{
using var response = await new HttpClient().GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead);
if (!response.IsSuccessStatusCode) return false;
using var streamToReadFrom = await response.Content.ReadAsStreamAsync();
using var zip = new ZipArchive(streamToReadFrom); // Blocks!
zip.ExtractToDirectory(directoryToUnzip);
return true;
}
What I see tracing with the debugger is that the ZipArchive
constructor blocks until the entire file is downloaded from the URI
This makes the bulk of the operation synchronous whereas I want both downloading and unzipping to be asynchronous.
What is the solution here ? how to make unzipping async ?
PS would be nice to have ExtractToDirectory
async as well
The ZipArchive
support in .NET only has some very basic asynchronous support.
You could download the stream into memory asynchronously (by removing HttpCompletionOption.ResponseHeadersRead
), and then do the unzipping:
async Task<bool> HttpDownloadAndUnzip(string requestUri, string directoryToUnzip)
{
using var response = await new HttpClient().GetAsync(requestUri);
if (!response.IsSuccessStatusCode) return false;
using var streamToReadFrom = await response.Content.ReadAsStreamAsync();
using var zip = new ZipArchive(streamToReadFrom);
zip.ExtractToDirectory(directoryToUnzip);
return true;
}
I'm not aware of any asynchronous implementations of ExtractToDirectory
in the BCL or any .NET library.