You have a large folder to archive inside a web request or desktop app. The ZIP APIs do the job, but the synchronous call keeps a thread occupied while the disk does all the real work.

The usual workaround was to wrap it in Task.Run. That moves the blocked thread. It doesn’t make the file work asynchronous.

.NET 10 adds real async APIs for creating, opening, updating, and extracting ZIP archives.

Try It

Create a .NET 10 console app:

Terminal window
dotnet new console -n AsyncZipDemo -f net10.0
cd AsyncZipDemo

Replace Program.cs with this:

using System.IO.Compression;
var workspace = Path.Combine(Path.GetTempPath(), "async-zip-demo");
var source = Path.Combine(workspace, "source");
var extracted = Path.Combine(workspace, "extracted");
var archive = Path.Combine(workspace, "backup.zip");
if (Directory.Exists(workspace))
{
Directory.Delete(workspace, recursive: true);
}
Directory.CreateDirectory(source);
await File.WriteAllTextAsync(
Path.Combine(source, "hello.txt"),
"Hello from .NET 10!");
await File.WriteAllTextAsync(
Path.Combine(source, "settings.json"),
"""{"theme":"dark","fontSize":18}""");
await ZipFile.CreateFromDirectoryAsync(
source,
archive,
CompressionLevel.Optimal,
includeBaseDirectory: false,
cancellationToken: CancellationToken.None);
await ZipFile.ExtractToDirectoryAsync(
archive,
extracted,
overwriteFiles: true,
cancellationToken: CancellationToken.None);
foreach (var file in Directory.EnumerateFiles(extracted))
{
Console.WriteLine($"{Path.GetFileName(file)}: {await File.ReadAllTextAsync(file)}");
}

Run it:

Terminal window
dotnet run

More Than Two Helper Methods

.NET 10 also adds async APIs lower in the stack:

await using var file = File.OpenRead("backup.zip");
using var archive = await ZipArchive.CreateAsync(
file,
ZipArchiveMode.Read,
leaveOpen: false,
entryNameEncoding: null,
cancellationToken: cancellationToken);
foreach (var entry in archive.Entries)
{
await using var entryStream = await entry.OpenAsync(cancellationToken);
// Read the entry without blocking a thread on file I/O.
}

That matters when you are working with uploaded streams, cloud storage, or archives that never touch a local filename.

When Not to Use It

Async doesn’t make compression itself free. The CPU work still has to happen. The win is that file and stream waits no longer pin a thread.

For a tiny ZIP created once in a console tool, the synchronous API is perfectly fine. Reach for async when the archive is large, the storage is slow, cancellation matters, or blocking a request thread would hurt.

Key Takeaway

.NET 10 gives ZIP files honest async support. You can create, extract, open, and update archives without hiding synchronous I/O inside Task.Run.