|
| 1 | +--- |
| 2 | +title: "Breaking change: ZipArchive.CreateAsync eagerly loads ZIP archive entries" |
| 3 | +description: "Learn about the breaking change in .NET 11 where ZipArchive.CreateAsync eagerly loads all ZIP archive entries to avoid synchronous reads on the stream." |
| 4 | +ms.date: 02/03/2026 |
| 5 | +ai-usage: ai-assisted |
| 6 | +--- |
| 7 | +# ZipArchive.CreateAsync eagerly loads ZIP archive entries |
| 8 | + |
| 9 | +<xref:System.IO.Compression.ZipArchive.CreateAsync%2A?displayProperty=nameWithType> now eagerly loads all ZIP archive entries during the method call. This change ensures that accessing the <xref:System.IO.Compression.ZipArchive.Entries?displayProperty=nameWithType> property doesn't perform synchronous reads on the underlying stream, which aligns with asynchronous programming patterns. |
| 10 | + |
| 11 | +## Version introduced |
| 12 | + |
| 13 | +.NET 11 Preview 1 |
| 14 | + |
| 15 | +## Previous behavior |
| 16 | + |
| 17 | +Previously, when you created a `ZipArchive` using `CreateAsync`, accessing the `Entries` property could result in synchronous (blocking) read operations being performed on the underlying stream. This behavior was inconsistent with the asynchronous nature of the `CreateAsync` method and could cause issues with streams that don't support synchronous reads. |
| 18 | + |
| 19 | +```csharp |
| 20 | +using System.IO; |
| 21 | +using System.IO.Compression; |
| 22 | + |
| 23 | +using var stream = new FileStream("archive.zip", FileMode.Open); |
| 24 | +using var archive = await ZipArchive.CreateAsync(stream, ZipArchiveMode.Read); |
| 25 | + |
| 26 | +// This call performs synchronous reads on the stream. |
| 27 | +// Might throw if the file entries are malformed |
| 28 | +// or if the stream doesn't support synchronous reads. |
| 29 | +var entries = archive.Entries; |
| 30 | +``` |
| 31 | + |
| 32 | +## New behavior |
| 33 | + |
| 34 | +Starting in .NET 11, the central directory of the ZIP archive is read asynchronously as part of the `ZipArchive.CreateAsync` method call. Any exceptions related to malformed entries or issues reading the central directory are now thrown during the `CreateAsync` call. Subsequent access to the `Entries` property doesn't perform any read operations on the underlying stream. |
| 35 | + |
| 36 | +```csharp |
| 37 | +using System.IO; |
| 38 | +using System.IO.Compression; |
| 39 | + |
| 40 | +using var stream = new FileStream("archive.zip", FileMode.Open); |
| 41 | + |
| 42 | +// This call eagerly loads the ZIP archive entries. |
| 43 | +// Any exceptions related to malformed entries are surfaced here. |
| 44 | +using var archive = await ZipArchive.CreateAsync(stream, ZipArchiveMode.Read); |
| 45 | + |
| 46 | +// Accessing Entries no longer performs stream read operations. |
| 47 | +var entries = archive.Entries; |
| 48 | +``` |
| 49 | + |
| 50 | +## Type of breaking change |
| 51 | + |
| 52 | +This change is a [behavioral change](../../categories.md#behavioral-change). |
| 53 | + |
| 54 | +## Reason for change |
| 55 | + |
| 56 | +This change was made to improve consistency and reliability when working with asynchronous streams. By eagerly loading entries during the `CreateAsync` call, the API avoids unexpected synchronous read operations later. Avoiding synchronous reads is especially important for streams that might end up blocking until data are available (such as network streams). This aligns with the approved API design and provides a more predictable programming experience. |
| 57 | + |
| 58 | +For more information, see [dotnet/runtime#121938](https://github.com/dotnet/runtime/pull/121938), [dotnet/runtime#121624](https://github.com/dotnet/runtime/issues/121624), and the [API design discussion](https://github.com/dotnet/runtime/issues/1541#issuecomment-2715269236). |
| 59 | + |
| 60 | +## Recommended action |
| 61 | + |
| 62 | +If your code uses `ZipArchive.CreateAsync`, ensure that you handle <xref:System.IO.InvalidDataException> exceptions from the `CreateAsync` method call. This exception could already be thrown in previous .NET versions (for example, when the ZIP central directory can't be found), but now it's also thrown for malformed entries that were previously only discovered when accessing the `Entries` property. |
| 63 | + |
| 64 | +## Affected APIs |
| 65 | + |
| 66 | +- <xref:System.IO.Compression.ZipArchive.CreateAsync(System.IO.Stream,System.IO.Compression.ZipArchiveMode,System.Boolean,System.Text.Encoding,System.Threading.CancellationToken)?displayProperty=fullName> |
| 67 | +- <xref:System.IO.Compression.ZipArchive.Entries?displayProperty=fullName> |
0 commit comments