dotnet/wpf · error · ObjectDisposedException

SR.ObjectDisposed_StoreClosed

Error message

SR.ObjectDisposed_StoreClosed

What it means

XmlStreamStore throws an ObjectDisposedException with resource key SR.ObjectDisposed_StoreClosed when CheckStatus() detects the annotation store has already been disposed (IsDisposed == true). The store is unusable after Dispose(); any annotation operation on it is invalid. This guards against operating on a closed backing stream.

Solutions

  1. Check store.IsDisposed before every operation and recreate the store from the stream if needed
  2. Ensure Dispose is only called after all annotation work (including Flush) is complete
  3. Restructure so the store lives inside a using block that scopes all annotation operations
  4. Catch ObjectDisposedException and re-open the store on the same stream

Example fix

// before
store.Dispose();
store.Flush(); // throws ObjectDisposedException

// after
if (!store.IsDisposed)
{
    store.Flush();
}
store.Dispose();
Defensive patterns

Strategy: try-catch

Validate before calling

if (store.IsDisposed) { store = RecreateStore(); }
if (!store.IsDisposed) store.Flush();

Type guard

bool Usable(XmlStreamStore s) => s != null && !s.IsDisposed;

Try / catch

try { store.Flush(); }
catch (ObjectDisposedException) { store = RecreateStore(); }

Prevention

When it happens

Trigger: Calling AddAnnotation, DeleteAnnotation, GetAnnotation, Flush, FindAnnotationIds, or InternalGetAnnotations after calling Dispose() on the XmlStreamStore instance.

Common situations: Disposing a store in a finally/using block and then calling Flush again; storing the store in a long-lived field while disposing it on window close but a background save still references it; double-dispose followed by retry logic that re-invokes store methods.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/Storage/XmlStreamStore.cs:930

                XPathNodeIterator iterator = tempNavigator.Select($@"//{AnnotationXmlConstants.Prefixes.CoreSchemaPrefix}:Annotation[@Id=""{XmlConvert.ToString(id)}""]", _namespaceManager);
                if (iterator.MoveNext())
                {
                    navigator = (XPathNavigator)iterator.Current;
                }
            }

            return navigator;
        }

        /// <summary>
        ///    Verifies the store is in a valid state.  Throws exceptions otherwise.
        /// </summary>
        private void CheckStatus()
        {
            lock (SyncRoot)
            {
                if (IsDisposed)
                    throw new ObjectDisposedException(null, SR.ObjectDisposed_StoreClosed);

                if (_stream == null)
                    throw new InvalidOperationException(SR.StreamNotSet);
            }
        }

        /// <summary>
        /// Called from flush to serialize all annotations in the map
        /// notice that delete takes care of the delete action both in the map
        /// and in the store
        /// </summary>
        private void SerializeAnnotations()
        {
            List<Annotation> mapAnnotations = _storeAnnotationsMap.FindDirtyAnnotations();
            foreach (Annotation annotation in mapAnnotations)
            {
                XPathNavigator editor = GetAnnotationNodeForId(annotation.Id);
                if (editor == null)

View on GitHub (pinned to 81131a70a4)