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

  1. Create a new XamlBackgroundReader instance for each XAML document rather than reusing one.
  2. Track whether StartThread has been called (or check the internal state) and guard the second call.
  3. 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

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


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/39a9fb350340ef33. Report an issue: GitHub.