Description
Description
When trying construct a ZipArchive
"on the fly" and serve it from the Web API, I have to turn-on the ASP.NET synchronous I/O mode, otherwise I get an exception when trying to create or write to ZIP entries. So far, I have encountered exceptions:
- when calling
Stream.WriteAsync
on the stream returned fromZipArchiveEntry.Open
, - and when calling
ZipArchive.CreateEntry
repeatedly (see the attached project).
Reproduction Steps
The following controller action illustrates the problem:
[HttpGet]
public async Task Get() {
using (var zip_archive = new ZipArchive(Response.Body, ZipArchiveMode.Create, true)) {
var zip_entry = zip_archive.CreateEntry("test.txt");
await using (var stream = zip_entry.Open()) {
// System.InvalidOperationException: 'Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.'
await stream.WriteAsync(Encoding.UTF8.GetBytes("Hello ZIP!"));
}
}
}
Here is a small project which illustrates the problem:
If you access the route /zip
or /zip2
you'll see the exception in the debugger and the corresponding diagnostic page in the browser.
Expected behavior
The ZIP archive is constructed and served without throwing any exceptions.
Actual behavior
The following exception is thrown:
System.InvalidOperationException: 'Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.'
Regression?
No response
Known Workarounds
The exception can be avoided by setting IHttpBodyControlFeature.AllowSynchronousIO
, as mentioned in aspnetcore / #7644.
That, of course, allows the ZIP code to "hog" the thread. It would be much better to upgrade the ZIP code to support true asynchronous I/O, which would benefit scalability and also remove the need for this workaround.
Configuration
.NET 8
Windows 11 Pro
x64
Other information
No response