{"record":{"id":"d2e76dfcdf31bedb","repo":"dotnet/wpf","slug":"sr-streamobjectdisposed","errorCode":null,"errorMessage":"SR.StreamObjectDisposed","messagePattern":"SR\\.StreamObjectDisposed","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CFStream.cs","lineNumber":283,"sourceCode":"        }\n\n        if( count != written )\n            throw new IOException(\n                SR.WriteFailure);\n}\n\n    //------------------------------------------------------\n    //\n    //  Internal Methods\n    //\n    //------------------------------------------------------\n\n    // Check whether this Stream object is still valid.  If not, thrown an\n    //  ObjectDisposedException.\n    internal void CheckDisposedStatus()\n    {\n        if( StreamDisposed )\n            throw new ObjectDisposedException(null, SR.StreamObjectDisposed);\n    }\n\n    // Check whether this Stream object is still valid.\n    internal bool StreamDisposed\n    {\n        get\n        {\n            return (backReference.StreamInfoDisposed || ( null == _safeIStream ));\n        }\n    }\n\n    // Constructors\n    internal CFStream(\n        IStream underlyingStream,\n        FileAccess openAccess,\n        StreamInfo creator)\n    {\n        _safeIStream = underlyingStream;","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CFStream.cs#L265-L301","documentation":"CFStream.CheckDisposedStatus throws ObjectDisposedException with SR.StreamObjectDisposed when any member (Length, Position, Flush, Seek, SetLength, Read, Write) is used after the CFStream has been disposed. Compound-file streams wrap native IStream handles that are released on Dispose, so further use is impossible. This is standard Stream disposed-state enforcement.","triggerScenarios":"Calling Read/Seek/Length/Position/Flush/SetLength/Write after calling Dispose() or after the containing CompoundFile was closed/disposed; using a stream captured in a lambda or event handler that fires after disposal.","commonSituations":"Using-block scope bugs where a stream reference escapes the using block; closing the parent Package/compound file while child streams are still referenced; async continuations running after the stream was disposed.","solutions":["Keep all stream usage inside the using/scope where the stream is alive","Check the parent CompoundFile/Package lifetime — disposing it disposes child streams","Track disposal with stream.CanRead (false after dispose) or a null-check after ownership transfer","Restructure so async work completes before disposing the owning file","Catch ObjectDisposedException as a last-resort guard in event handlers"],"exampleFix":"// before\nStream s;\nusing (var cf = new CompoundFile(path)) {\n    s = cf.OpenStream(name);\n}\ns.Read(buf, 0, buf.Length); // throws\n// after\nusing (var cf = new CompoundFile(path)) {\n    using (var s = cf.OpenStream(name)) {\n        s.Read(buf, 0, buf.Length);\n    }\n}","handlingStrategy":"type-guard","validationCode":"if (stream == null || !stream.CanRead) throw new ObjectDisposedException(nameof(stream));","typeGuard":"static bool IsUsable(Stream s) => s != null && s.CanRead;","tryCatchPattern":"try { stream.Read(buffer, 0, count); } catch (ObjectDisposedException) { /* reopen the stream */ }","preventionTips":["Confine stream usage to using blocks; never let references escape","Know the owner: disposing the CompoundFile/Package disposes its streams","Complete async work before disposing the owning object","Set fields to null after disposal to fail fast on stale references"],"tags":["object-disposed","stream-lifetime","io","wpf"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}