unoplatform/uno · error · InvalidOperationException
Thread has already started
Error message
Thread has already started
What it means
Thrown by XamlBackgroundReader.StartThread when the background reader thread has already been launched (thread field is non-null). XamlBackgroundReader is a single-use component that spawns exactly one reader thread; calling StartThread twice would corrupt the node queue and duplicate processing.
Source
Thrown at src/SourceGenerators/System.Xaml/System.Xaml/XamlBackgroundReader.cs:106
do_work = false;
}
public override bool Read ()
{
if (q.IsEmpty)
wait.WaitOne ();
return q.Reader.Read ();
}
public void StartThread ()
{
StartThread ("XAML reader thread"); // documented name
}
public void StartThread (string threadName)
{
if (thread != null)
throw new InvalidOperationException ("Thread has already started");
thread = new Thread (new ParameterizedThreadStart (delegate {
while (do_work && r.Read ()) {
q.Writer.WriteNode (r);
wait.Set ();
}
read_all_done = true;
})) { Name = threadName };
thread.Start ();
}
}
}
View on GitHub (pinned to 0418340488)
Solutions
- Create a new XamlBackgroundReader instance for each XAML document rather than reusing one.
- Track whether StartThread has been called (or check the internal state) and guard the second call.
- Restructure the pipeline so each document gets its own reader lifecycle.
Example fix
// before reader.StartThread(); // ... process ... reader.StartThread(); // throws // after reader.StartThread(); // ... process ... reader = new XamlBackgroundReader(schemaContext, innerReader); reader.StartThread();
Defensive patterns
Strategy: validation
Validate before calling
if (reader.ThreadStarted) throw new InvalidOperationException("already started");
reader.StartThread();
// or simply create a new reader per document Try / catch
try { reader.StartThread(); }
catch (InvalidOperationException) { reader = new XamlBackgroundReader(sctx, inner); reader.StartThread(); } Prevention
- Create a new XamlBackgroundReader for each XAML document.
- Never reuse a reader across documents — treat it as single-use.
When it happens
Trigger: Calling StartThread() (or StartThread(name)) a second time on the same XamlBackgroundReader instance. This commonly happens when reader code is reused across passes or when a retry/error-recovery path re-invokes Start.
Common situations: XAML processing pipeline that attempts to restart a failed read. Caching and reusing an XamlBackgroundReader for multiple documents. Misconfigured reader lifecycle management that does not create a fresh reader per document.
Related errors
- Namespace must be set before calling ToString method.
- Name must be set before calling ToString method.
- There is already an object of type {0} named as '{1}'. Objec
- typeArguments array contains one or more null XamlTypeName
- Could not lookup prefix for namespace '{0}'
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/39a9fb350340ef33.
Report an issue: GitHub.