{"record":{"id":"ebcc7538c8850af5","repo":"dotnet/wpf","slug":"sr-threadalreadystarted","errorCode":null,"errorMessage":"SR.ThreadAlreadyStarted","messagePattern":"SR\\.ThreadAlreadyStarted","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlBackgroundReader.cs","lineNumber":87,"sourceCode":"                xamlNodeNextDelegate = new XamlNodeNextDelegate(Next);\n            }\n\n            _internalReader = new ReaderDelegate(_wrappedReader.SchemaContext, xamlNodeNextDelegate, _wrappedReaderHasLineInfo);\n\n            // Standin so it won't start null\n            _currentNode = new XamlNode(XamlNode.InternalNodeType.StartOfStream);\n        }\n\n        public void StartThread()\n        {\n            StartThread(\"XAML reader thread\");\n        }\n\n        public void StartThread(string threadName)\n        {\n            if (_thread is not null)\n            {\n                throw new InvalidOperationException(SR.ThreadAlreadyStarted);\n            }\n\n            ParameterizedThreadStart start = new ParameterizedThreadStart(XamlReaderThreadStart);\n            _thread = new Thread(start)\n            {\n                Name = threadName\n            };\n            _thread.Start();\n        }\n\n        // The \"ThreadStart\" function\n        private void XamlReaderThreadStart(object none)\n        {\n            try\n            {\n                InterruptableTransform(_wrappedReader, _writer, true);\n            }\n            catch (Exception ex)","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlBackgroundReader.cs#L69-L105","documentation":"XamlBackgroundReader.StartThread starts a single background read thread; if _thread is already created it throws InvalidOperationException(SR.ThreadAlreadyStarted). Each reader instance may only start its background thread once.","triggerScenarios":"Calling StartThread(name) twice on the same XamlBackgroundReader instance, e.g. calling it manually after the reader already auto-started, or calling it again after a prior successful start in retry logic.","commonSituations":"Re-initializing a reader that was reused across parse runs; wrapper layers and unit helpers both calling StartThread; code that retries StartThread after an unrelated failure assuming the thread never launched.","solutions":["Call StartThread exactly once per reader instance; create a new XamlBackgroundReader for a fresh read cycle.","Guard the call: only invoke StartThread when the thread has not been started yet.","Move StartThread to a single construction/initialization point rather than call sites scattered across code.","Catch InvalidOperationException for ThreadAlreadyStarted if double-start is possible in your flow."],"exampleFix":"// before\nreader.StartThread(\"xaml\");\nreader.StartThread(\"xaml-retry\"); // throws\n// after\nif (readerStarted) reader = new XamlBackgroundReader(...);\nreader.StartThread(\"xaml\");\nreaderStarted = true;","handlingStrategy":"validation","validationCode":"if (readerThreadStarted) throw new InvalidOperationException(\"StartThread already called on this XamlBackgroundReader.\");\nreader.StartThread(\"xaml\");\nreaderThreadStarted = true;","typeGuard":null,"tryCatchPattern":"try { reader.StartThread(name); } catch (InvalidOperationException ex) when (/* ThreadAlreadyStarted */) { /* reuse existing thread or recreate reader */ }","preventionTips":["Call StartThread once per reader instance","Centralize reader initialization","Recreate the reader for each new parse run"],"tags":["xaml","threading","double-initialization"],"backgroundTag":"invalid-state-transition","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"}