dotnet/wpf · error · ObjectDisposedException
SR.StreamObjectDisposed
Error message
SR.StreamObjectDisposed
What it means
ObjectDisposedException with message SR.StreamObjectDisposed thrown by SparseMemoryStream.CheckDisposed, called at the start of Length, Position, SetLength, Seek, Read and Write. SparseMemoryStream is the backing store for sparse in-memory package parts; once disposed its state (including block list) is invalid and any operation must fail.
Solutions
- Complete all reads/writes before disposing the package or part stream.
- Re-acquire the stream via part.GetStream() if it was closed.
- Guard long-lived references: null them out on dispose so misuse surfaces immediately.
- Restructure ownership so the stream's lifetime is contained in one scope.
Example fix
// before _sparseStream = new SparseMemoryStream(); ... _sparseStream.Dispose(); _sparseStream.WriteByte(b); // throws // after _sparseStream.Dispose(); _sparseStream = null; if (_sparseStream != null) _sparseStream.WriteByte(b);
Defensive patterns
Strategy: try-catch
Type guard
bool IsAlive(SparseMemoryStream s) => s is { CanRead: true } or { CanWrite: true }; Try / catch
try { stream.WriteByte(b); }
catch (ObjectDisposedException) { /* stream closed: reopen via owning package */ } Prevention
- Tie stream usage to the package lifetime with using
- Null out stream references after dispose
- Avoid background tasks holding part-stream references
When it happens
Trigger: Any stream operation on a SparseMemoryStream after Dispose — typically after the containing package or part stream was closed and the wrapped reference is reused.
Common situations: Retaining a MemoryStream-backed part stream across Package.Close; deferred writes to a part whose stream was disposed by an outer using; double-dispose followed by read.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.StreamObjectDisposed
- Cannot access Stream object because it was closed or…
- A read or write operation references a location outside the…
- Cannot change content of read-only stream.
- Cannot set seek pointer to a negative position.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f6491f6b6372b5ac.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/SparseMemoryStream.cs:454
internal long MemoryConsumption
{
get
{
CheckDisposed();
return _trackingMemoryStreamFactory.CurrentMemoryConsumption;
}
}
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
private void CheckDisposed()
{
if (_disposedFlag)
{
throw new ObjectDisposedException(SR.StreamObjectDisposed);
}
}
private MemoryStreamBlock GetSearchBlockForOffset(long offset)
{
if (_searchBlock == null)
_searchBlock = new MemoryStreamBlock(null, offset);
else
_searchBlock.Offset = offset;
return _searchBlock;
}
private bool CanCollapseWithPreviousBlock(MemoryStreamBlock memStreamBlock,
long offset,
long length)
{
// There was an explicit request by the client not to merge near- by blocks
if (!_autoCloseSmallBlockGaps || memStreamBlock == null)View on GitHub (pinned to 81131a70a4)