dotnet/wpf · warning · ObjectDisposedException

NLGSpellerInterop.SpellerSentence

Error message

NLGSpellerInterop.SpellerSentence

What it means

NLGSpellerInterop.SpellerSentence.Dispose(bool) throws ObjectDisposedException (message "NLGSpellerInterop.SpellerSentence") when the sentence has already been disposed. This prevents double-release of native segment resources owned by the sentence.

Solutions

  1. Give a single owner responsibility for sentence disposal.
  2. Guard disposal with an isDisposed flag in the calling code.
  3. Catch ObjectDisposedException during teardown.
  4. Set the sentence reference to null after disposal.

Example fix

// before
cleanup(sentence);
sentence.Dispose(); // second dispose throws
// after
sentence?.Dispose();
sentence = null;
Defensive patterns

Strategy: try-catch

Try / catch

try { sentence.Dispose(); }
catch (ObjectDisposedException) { /* ignore in teardown */ }

Prevention

When it happens

Trigger: Calling Dispose twice on a SpellerSentence - typically once in a spell-check pass loop and again during teardown/invalidation of the text chunk.

Common situations: Re-checking text regions where old sentences are disposed both by the re-check logic and by the chunk cleanup; cancellation paths racing with normal disposal.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/1250766860e2cd4b. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs:898

                    return endOffset;
                }
            }

            #endregion SpellerInteropBase.ISpellerSentence

            #region IDisposable

            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }

            protected virtual void Dispose(bool disposing)
            {
                if (_disposed)
                {
                    throw new ObjectDisposedException("NLGSpellerInterop.SpellerSentence");
                }

                if (_segments != null)
                {
                    foreach (SpellerSegment segment in _segments)
                    {
                        segment.Dispose();
                    }

                    _segments = null;
                }

                _disposed = true;                
            }

            ~SpellerSentence()
            {
                Dispose(false);

View on GitHub (pinned to 81131a70a4)