{"record":{"id":"711701bbfc0d5a32","repo":"dotnet/wpf","slug":"sr-media-streamclosed","errorCode":null,"errorMessage":"SR.Media_StreamClosed","messagePattern":"SR\\.Media_StreamClosed","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/StreamAsIStream.cs","lineNumber":501,"sourceCode":"                canSeek = dataStream.CanSeek;\n            }\n            catch (Exception e)\n            {\n                // store the last exception\n                _lastException = e;\n                return SecurityHelper.GetHRForException(e);\n            }\n\n            return NativeMethods.S_OK;\n        }\n        #endregion\n\n        #region Verify\n        private void Verify()\n        {\n            if (this.dataStream == null)\n            {\n                throw new System.ObjectDisposedException(SR.Media_StreamClosed);\n            }\n        }\n        #endregion\n\n        #region Delegate Implemetations\n        internal static StreamAsIStream FromSD(ref StreamDescriptor sd)\n        {\n            Debug.Assert(((IntPtr)sd.m_handle) != IntPtr.Zero, \"Stream is disposed.\");\n            System.Runtime.InteropServices.GCHandle handle = (System.Runtime.InteropServices.GCHandle)(sd.m_handle);\n            return (StreamAsIStream)(handle.Target);\n        }\n\n        internal static int Clone(ref StreamDescriptor pSD, out IntPtr stream)\n        {\n            return (StreamAsIStream.FromSD(ref pSD)).Clone(out stream);\n        }\n\n        internal static int Commit(ref StreamDescriptor pSD, UInt32 grfCommitFlags)","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/StreamAsIStream.cs#L483-L519","documentation":"StreamAsIStream.Verify throws ObjectDisposedException when the wrapped dataStream is null, i.e. the underlying Stream has been closed/disposed after the StreamAsIStream wrapper was created (used by WPF's media layer to expose a managed Stream to unmanaged code). The wrapper remains usable only while its source stream is open.","triggerScenarios":"Any IStream-style operation on a StreamAsIStream after its underlying Stream was disposed or closed (e.g. media pipeline still reading a stream the app disposed, or FromSD-created wrapper outliving the source).","commonSituations":"Disposing a MemoryStream/FileStream that a MediaElement/MediaPlayer is still consuming; closing the stream in a using block while async media playback continues.","solutions":["Keep the underlying Stream open for the lifetime of the media object; dispose it only after MediaElement/MediaPlayer is closed","Remove 'using' around streams handed to media APIs and manage lifetime explicitly","Check stream disposal order in async scenarios; ensure playback stopped before disposing"],"exampleFix":"// before\nusing (var fs = File.OpenRead(\"clip.wmv\"))\n{\n    player.Open(new Uri(fs.Name)); // stream disposed when block exits\n}\n// after\nvar fs = File.OpenRead(\"clip.wmv\");\nplayer.Open(new Uri(fs.Name));\nplayer.MediaEnded += (s, e) => fs.Dispose();","handlingStrategy":"try-catch","validationCode":"if (stream == null || !stream.CanRead) throw new ObjectDisposedException(nameof(stream));","typeGuard":"bool IsOpen(Stream s) => s != null && s.CanRead;","tryCatchPattern":"try { /* IStream operation */ } catch (ObjectDisposedException ex) { /* recreate stream and re-run media setup */ }","preventionTips":["Never wrap media source streams in using; dispose on MediaEnded/Closed","Stop media playback before disposing streams","Audit async paths for stream lifetime outliving the disposal scope"],"tags":["wpf","media","stream-disposed"],"backgroundTag":"resource-disposed","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"}