Search code examples
c#async-awaithttprequestunzip

Download and unzip file asynchronically


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


Solution

  • 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.