-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Description
Library name
Azure.Storage.Blobs
Please describe the feature.
Currently, when using BlobClient.OpenWriteAsync(...) (or BlockBlobClient.OpenWriteAsync(...)) to obtain a writable stream, the SDK automatically commits all staged blocks when the stream is disposed — including cases where the application encounters an exception before the write completes.
This creates a problematic pattern:
await using var stream = await blobClient.OpenWriteAsync(overwrite: true);
// some logic that may throw before writing or finishing
await stream.WriteAsync(data);If an exception occurs after obtaining the stream but before writing is complete, the await using scope still triggers DisposeAsync(), which commits all staged blocks.
As a result, a blob may end up partially written or corrupted, even though the write failed from the application's perspective.
Current Workaround
Currently, the only reliable workaround is to manually stage blocks using StageBlockAsync() and call CommitBlockListAsync() only after a successful write.
This approach works but sacrifices the simplicity and convenience of OpenWriteAsync.
Suggested Solution
Instead of returning a plain Stream, the method could return a new type such as BlobCommittableStream, which would expose an explicit .Commit() method.
This would allow the caller to decide when the upload is finalized rather than having it automatically committed on disposal.
To preserve backward compatibility, an overload could be added to OpenWriteAsync:
Task<Stream> OpenWriteAsync(
bool overwrite = false,
BlobOpenWriteOptions options = default,
CancellationToken cancellationToken = default,
bool autoCommit = true)When autoCommit is true (the default), the current behavior would remain unchanged.
When autoCommit is false, the caller would need to explicitly call .CommitAsync() on the returned stream to finalize the upload.
Environment
- Library:
Azure.Storage.Blobs - Version: 12.23.0
- Framework: .NET 8