Parallel downloading multiple files from azure storage and create zip file.

Mohammad Nasir Uddin 46 Reputation points
2023-07-09T07:19:49.6666667+00:00

I have a Background Worker Process, where I need to download multiple files from Azure Storage and then create a ZIP file with those files. All the process will be done in memory.

So, I created the below code.

SemaphoreSlim semaphore = new(1, 1);
ParallelOptions options = new() { MaxDegreeOfParallelism = 10 };

using (MemoryStream zipStream = new MemoryStream())
{
	using (ZipArchive zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Update, false))
	{
		Parallel.ForEach(supportingDocLists, options, supportingDoc =>
		{
			if (!string.IsNullOrWhiteSpace(supportingDoc.FileURL) && !string.IsNullOrWhiteSpace(supportingDoc.FileName))
			{
				BlobClient blobClient = containerClient.GetBlobClient(supportingDoc.FileURL);
				
				if (blobClient.Exists())
				{
					BlobDownloadInfo downloadInfo = blobClient.Download();

					// Store it in the zip file sequentially.
					//semaphore.Wait();
					
					ZipArchiveEntry zipEntry = zipArchive.CreateEntry(supportingDoc.FileName);
					lock(zipEntry)
					{
						using (Stream entryStream = zipEntry.Open())
						{
							blobClient.DownloadTo(entryStream);
						}
					}                                    
				}                                
			}
		});
	}

	zipStream.Position = 0;
	return zipStream.ToArray();

But the code is not working properly. I am having the exception (Cannot access a closed stream). Can anyone help me to resolve the problem.

User's image

Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
3,199 questions
Developer technologies | ASP.NET | ASP.NET Core
0 comments No comments
{count} votes

Accepted answer
  1. Chen Li - MSFT 1,231 Reputation points
    2023-07-10T08:15:25.3933333+00:00

    Hi @Nasir Uddin,

    When using using, it disposes the object and closes the stream being used. Do not use using statement for MemoryStream:

    MemoryStream zipStream = new MemoryStream();
    using (ZipArchive zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Update, false))
    {
    }
    

    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best Regards,

    Chen Li

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.