dotnet/wpf · error · ObjectDisposedException
BaseStream
Error message
BaseStream
What it means
SharedStream's CheckDisposed guard throws ObjectDisposedException with objectName "BaseStream" when any member (CanRead, CanWrite, Flush, ReadByte, Read, Write, Seek) is used after the stream has been disposed. The underlying base stream was disposed and this shared view is no longer usable.
Solutions
- Keep the SharedStream (and its base stream) alive for the whole duration of Baml2006Reader usage — dispose the reader and stream together, reader first.
- Move the stream creation and reader consumption into the same scope; await all reads before exiting using.
- Guard with stream.CanRead or a disposed flag before reuse if the lifetime is uncertain.
- Fix ownership: whoever created the base stream should dispose it last.
Example fix
// before
SharedStream s;
using (var fs = File.OpenRead(path))
{
s = new SharedStream(fs, 0, fs.Length);
} // fs disposed here
s.ReadByte(); // ObjectDisposedException
// after
using (var fs = File.OpenRead(path))
using (var s = new SharedStream(fs, 0, fs.Length))
{
// consume s fully inside this scope
var reader = new Baml2006Reader(s);
...
} Defensive patterns
Strategy: type-guard
Validate before calling
// Guard every use after possible disposal if (!stream.CanRead) throw new ObjectDisposedException(nameof(stream));
Type guard
static bool IsUsable(Stream? s) => s is { CanRead: true }; Try / catch
try
{
int b = stream.ReadByte();
}
catch (ObjectDisposedException ex) when (ex.ObjectName == "BaseStream")
{
// re-open resource and rebuild the SharedStream if retry is safe
throw new InvalidOperationException("SharedStream used after disposal; keep stream alive for the reader's lifetime.", ex);
} Prevention
- Scope the using blocks so SharedStream and Baml2006Reader dispose together (reader first)
- Never stash a SharedStream in a field beyond its source stream's using scope
- Await all async reads before disposing the source
- Check CanRead before reuse when ownership is unclear
When it happens
Trigger: Using the SharedStream after calling Dispose() or after a using block ended — e.g. reading BAML from a stream closed when its owning resource/file context exited, or a deferred/async read running after disposal.
Common situations: Async XAML loading outliving the using-scope that opened the resource stream; disposing a package/resource stream while a Baml2006Reader still holds the SharedStream; double-dispose then reuse.
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
- ArgumentOutOfRangeException(nameof(offset))
- ArgumentOutOfRangeException: offset is outside the valid…
- can’t seek on baseStream
- Current stream object was closed and disposed. Cannot…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/dd22ad5ce3b9fa1d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/SharedStream.cs:282
}
_refCount = null;
_baseStream = null;
}
}
base.Dispose(disposing);
}
public Stream BaseStream
{
get { return _baseStream; }
}
private void CheckDisposed()
{
if (IsDisposed)
{
throw new ObjectDisposedException("BaseStream");
}
}
private bool Sync()
{
System.Diagnostics.Debug.Assert(_baseStream != null, "Stream has already been disposed");
if (_position >= 0 && _position < _length)
{
if (_position + _offset != _baseStream.Position)
_baseStream.Seek(_offset + _position, SeekOrigin.Begin);
return true;
}
return false;
}
private class RefCountView on GitHub (pinned to 81131a70a4)