{"record":{"id":"1250766860e2cd4b","repo":"dotnet/wpf","slug":"nlgspellerinterop-spellersentence","errorCode":null,"errorMessage":"NLGSpellerInterop.SpellerSentence","messagePattern":"NLGSpellerInterop\\.SpellerSentence","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"warning","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs","lineNumber":898,"sourceCode":"                    return endOffset;\n                }\n            }\n\n            #endregion SpellerInteropBase.ISpellerSentence\n\n            #region IDisposable\n\n            public void Dispose()\n            {\n                Dispose(true);\n                GC.SuppressFinalize(this);\n            }\n\n            protected virtual void Dispose(bool disposing)\n            {\n                if (_disposed)\n                {\n                    throw new ObjectDisposedException(\"NLGSpellerInterop.SpellerSentence\");\n                }\n\n                if (_segments != null)\n                {\n                    foreach (SpellerSegment segment in _segments)\n                    {\n                        segment.Dispose();\n                    }\n\n                    _segments = null;\n                }\n\n                _disposed = true;                \n            }\n\n            ~SpellerSentence()\n            {\n                Dispose(false);","sourceCodeStart":880,"sourceCodeEnd":916,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs#L880-L916","documentation":"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.","triggerScenarios":"Calling Dispose twice on a SpellerSentence - typically once in a spell-check pass loop and again during teardown/invalidation of the text chunk.","commonSituations":"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.","solutions":["Give a single owner responsibility for sentence disposal.","Guard disposal with an isDisposed flag in the calling code.","Catch ObjectDisposedException during teardown.","Set the sentence reference to null after disposal."],"exampleFix":"// before\ncleanup(sentence);\nsentence.Dispose(); // second dispose throws\n// after\nsentence?.Dispose();\nsentence = null;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { sentence.Dispose(); }\ncatch (ObjectDisposedException) { /* ignore in teardown */ }","preventionTips":["Dispose each sentence exactly once in the spell-check loop","Track disposed sentences in a HashSet during cleanup","Null references after disposal"],"tags":["dispose","wpf","spellcheck","object-disposed"],"backgroundTag":"object-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"}