{"record":{"id":"e361beb0b4196a1e","repo":"dotnet/wpf","slug":"cannot-access-stream-object-because-it-was-closed-or","errorCode":null,"errorMessage":"Cannot access Stream object because it was closed or disposed.","messagePattern":"Cannot access Stream object because it was closed or disposed\\.","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/PrivateUnsafeNativeCompoundFileMethods.cs","lineNumber":105,"sourceCode":"            /// <param name=\"disposing\"></param>\n            protected virtual void Dispose(bool disposing)\n            {\n                if (disposing && (_baseStream != null))\n                {\n                    // We only set the _baseStream to null without closing it,\n                    // because _baseStream is a reference of an outside stream,\n                    // and was set when this class was constructed. We didn't open \n                    // the stream and should leave the original owner of the stream\n                    // to close it.\n                    _baseStream = null;\n                }\n            }\n\n            private void CheckDisposed()\n            {\n                if (_baseStream==null)\n                {\n                    throw new ObjectDisposedException(null, SR.StreamObjectDisposed);\n                }\n            }\n\n            void UnsafeNativeILockBytes.ReadAt (\n                UInt64 offset,\n                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] Byte[] pv,\n                int cb,\n                out int pcbRead)\n            {\n                CheckDisposed();\n                checked { _baseStream.Seek( (long)offset, SeekOrigin.Begin ); }\n                pcbRead = _baseStream.Read( pv, 0, cb );\n            }\n\n            void UnsafeNativeILockBytes.WriteAt(\n                UInt64 offset,\n                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Byte[] pv,\n                int cb,","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/PrivateUnsafeNativeCompoundFileMethods.cs#L87-L123","documentation":"UnsafeLockBytesOnStream implements CheckDisposed, called by every ILockBytes operation (ReadAt, WriteAt, Flush, SetSize, Stat). After Dispose has been called, _baseStream is set to null, and any subsequent operation throws ObjectDisposedException with the 'Cannot access Stream object because it was closed or disposed' message.","triggerScenarios":"Calling any ILockBytes/IStream operation after UnsafeLockBytesOnStream.Dispose() — e.g. using the compound file object after its owning Package/stream was closed, or a callback firing after disposal.","commonSituations":"Double-closing a Package (using-block plus explicit Dispose), holding a reference to a compound-file stream after the parent package is closed, or async operations outliving the stream's lifetime.","solutions":["Ensure the underlying stream lives as long as all uses of the compound file; only dispose once, after all operations complete.","Guard accesses with a disposed check, or catch ObjectDisposedException where post-dispose calls are benign.","Restructure so callbacks/async work complete before disposing the owning Package."],"exampleFix":"// before\npackage.Close();\nvar stat = lockBytes.Stat(0); // throws\n// after\nvar stat = lockBytes.Stat(0);\npackage.Close();","handlingStrategy":"try-catch","validationCode":"bool usable = lockBytes != null && !isDisposed; // track your own disposed flag","typeGuard":"bool IsAlive(UnsafeLockBytesOnStream lb) => lb != null && !lb.Disposed;","tryCatchPattern":"try { lockBytes.Stat(grfStatFlag); }\ncatch (ObjectDisposedException) { /* stream was closed; reopen or abort */ }","preventionTips":["Dispose exactly once, after all operations complete","Avoid double disposal (using-block + explicit Close)","Ensure async/callback work finishes before closing the parent Package"],"tags":["object-disposed","stream","lifecycle","packaging"],"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"}