dotnet/wpf · error · ObjectDisposedException

SR.StreamObjectDisposed

Error message

SR.StreamObjectDisposed

What it means

ObjectDisposedException with message SR.StreamObjectDisposed thrown by IgnoreFlushAndCloseStream.ThrowIfStreamDisposed, a guard invoked by every public stream member (Length, Position, Seek, SetLength, Read, Write). IgnoreFlushAndCloseStream wraps an inner stream to suppress Flush/Close; once the wrapper is disposed any further use fails.

Solutions

  1. Keep the stream inside a using block and finish all I/O before disposing the package.
  2. Reopen the PackagePart stream if you need to continue writing after close.
  3. Restructure code so the package outlives all uses of its part streams.
  4. Check ObjectDisposedException.IsDisposed-style guards by tracking lifetime explicitly rather than catching.

Example fix

// before
Stream s = part.GetStream();
package.Close();
s.Write(data, 0, data.Length); // throws
// after
using (Stream s = part.GetStream())
{
    s.Write(data, 0, data.Length);
}
package.Close();
Defensive patterns

Strategy: try-catch

Type guard

bool IsUsable(Stream s) => s is { CanRead: true } or { CanWrite: true };

Try / catch

try { stream.Write(buffer, 0, buffer.Length); }
catch (ObjectDisposedException) { stream = part.GetStream(); /* reopen and retry */ }

Prevention

When it happens

Trigger: Calling Read, Write, Seek, Position, Length or SetLength on an IgnoreFlushAndCloseStream after Dispose was called on it (often indirectly by closing the owning package or part).

Common situations: Using a PackagePart stream reference after the Package was closed; caching a part stream across a using-scope; writing to a stream captured before a Package.Close/Dispose call.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/IgnoreFlushAndCloseStream.cs:207

                if (!_disposed)
                {
                    _stream = null;
                    _disposed = true;
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
        }


        #region Private Methods

        private void ThrowIfStreamDisposed()
        {
            if (_disposed)
                throw new ObjectDisposedException(null, SR.StreamObjectDisposed);
        }

        #endregion Private Methods

        #region Private Variables

        private Stream _stream;
        private bool _disposed;

        #endregion Private Variables
    }    
}

View on GitHub (pinned to 81131a70a4)