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

  1. Keep the SharedStream (and its base stream) alive for the whole duration of Baml2006Reader usage — dispose the reader and stream together, reader first.
  2. Move the stream creation and reader consumption into the same scope; await all reads before exiting using.
  3. Guard with stream.CanRead or a disposed flag before reuse if the lifetime is uncertain.
  4. 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

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


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 RefCount

View on GitHub (pinned to 81131a70a4)