dotnet/wpf · error · ObjectDisposedException

Current stream object was closed and disposed. Cannot…

Error message

Current stream object was closed and disposed. Cannot access a closed stream.

What it means

ByteStream wraps a Stream for WPF packaging and tracks disposal via a StreamDisposed flag. Any member (Length, Position, Seek, Read) calls CheckDisposedStatus() first and throws ObjectDisposedException once the underlying stream has been closed/disposed. It prevents use-after-dispose on package part streams.

Solutions

  1. Keep the source stream (and its Package) open until all reads of the package part are finished; scope using blocks around all consuming code.
  2. Wrap stream access in try-catch for ObjectDisposedException and re-open the stream if it was closed.
  3. Check the stream's CanRead property before accessing it and reopen/re-create the ByteStream when it is false.

Example fix

// before
using (var fs = File.OpenRead(path)) {
    var bs = new ByteStream(fs);
    QueueReadLater(bs); // fs disposed here -> later access throws
}
// after
var fs = File.OpenRead(path);
var bs = new ByteStream(fs);
try {
    ReadAll(bs); // consume while stream is open
} finally {
    fs.Dispose();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (stream == null || !stream.CanRead) { /* re-open the stream before constructing/using ByteStream */ }

Type guard

static bool IsUsable(Stream s) => s != null && (s.CanRead || s.CanWrite);

Try / catch

try { var len = byteStream.Length; } catch (ObjectDisposedException) { /* re-open stream and retry */ }

Prevention

When it happens

Trigger: Calling Read, Seek, Position, or Length on a ByteStream after its Stream was closed via Stream.Close()/Dispose(), or after the containing package was closed and disposed its part streams.

Common situations: Disposing a Package or FileStream in a using block while still reading XPS/package parts from it; closing the stream in a finally block before a delayed read; sharing a stream between code paths where one disposes it early.

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/9f9189bc89bee383. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/ByteStream.cs:346

        #endregion Public Methods


        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        #region Internal Methods

        /// <summary>
        /// Check whether this Stream object is still valid.  If not, thrown an
        /// ObjectDisposedException.
        /// </summary>
        internal void CheckDisposedStatus()
        {
            if (StreamDisposed)
                throw new ObjectDisposedException(null, SR.StreamObjectDisposed);
        }

        #endregion Internal Methods


        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        #region Internal Properties

        /// <summary>
        /// Check whether this Stream object is still valid.
        /// </summary>
        private bool StreamDisposed
        {
            get

View on GitHub (pinned to 81131a70a4)