dotnet/wpf · warning · ObjectDisposedException
NLGSpellerInterop.SpellerSegment
Error message
NLGSpellerInterop.SpellerSegment
What it means
NLGSpellerInterop.SpellerSegment.Dispose(bool) throws ObjectDisposedException (message "NLGSpellerInterop.SpellerSegment") when Dispose is called on an already-disposed segment. Like the outer interop class, this nested type's Dispose is not idempotent.
Solutions
- Dispose each SpellerSegment exactly once; let SpellerSentence own and dispose its segments.
- Add an ownership convention: only the parent (sentence) disposes segments.
- Catch ObjectDisposedException in bulk cleanup loops.
- Null out references after disposal to prevent accidental re-disposal.
Example fix
// before foreach (var seg in sentence.Segments) seg.Dispose(); sentence.Dispose(); // may double-dispose segments // after sentence.Dispose(); // sentence disposes its own segments once
Defensive patterns
Strategy: try-catch
Try / catch
try { segment.Dispose(); }
catch (ObjectDisposedException) { /* ignore in cleanup */ } Prevention
- Let SpellerSentence own segment lifetime
- Never dispose both parent and child explicitly
- Null out segment references after disposal
When it happens
Trigger: Disposing a SpellerSegment twice - e.g. iterating subSegments and disposing each, then disposing parent segments that dispose their children again, or explicit plus finalizer cleanup.
Common situations: Manual spell-check span management where both the sentence loop and segment loop release the same child segments; repeated teardown after spell-check cancellation.
Related errors
- NLGSpellerInterop.SpellerSentence
- SR.TextEditorSpellerInteropHasBeenDisposed
- EncryptedPackageEnvelope object was disposed.
- FixedPageReader
- SR.ByteRangeDownloaderDisposed
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ed08431a0a502f8f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs:743
}
}
#endregion SpellerInteropBase.ISpellerSegment
#region IDisposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
throw new ObjectDisposedException("NLGSpellerInterop.SpellerSegment");
}
if (_subSegments != null)
{
foreach (SpellerSegment subSegment in _subSegments)
{
// Don't call Dispose(disposing) here. That will
// fail to suppress finalization of subsegment objects.
subSegment.Dispose();
}
_subSegments = null;
}
if (_textSegment != null)
{
Marshal.ReleaseComObject(_textSegment);
_textSegment = null;
}View on GitHub (pinned to 81131a70a4)