mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
The crash is a NullReferenceException in GetNodeByVisibleIndex, reached when a background decompile realizes a node's children while the UI thread is indexing the flattener. Eight ILSpyTreeNode.Decompile overrides call EnsureLazyChildren from that task; two wrapped it in Dispatcher.UIThread.Invoke, six did not, and one of the two lost its wrapper in the Avalonia port with no test noticing for a release cycle. A rule every call site has to remember is a rule that gets broken again, so EnsureLazyChildren marshals itself instead: SetOwner already named the owning thread, and now also carries the host's way onto it. A call already on the owner runs inline, so a blocking invoke cannot deadlock on itself and a nested load costs no further hop; an unowned tree is left unmarshalled, which keeps building a subtree on a worker and publishing it on the UI thread legal. The affinity check stays as the regression detector, but its fail-fast throw was worthless on its own: tree mutation happens inside callers that catch Exception, so the throw ended up rendered into the decompiled output and the run passed. The violation is now recorded before the throw, and an assembly-level NUnit test action fails the test that produced one - an assembly-level teardown failure is reported but leaves the exit code at zero. Assisted-by: Claude:claude-opus-5:Claude Code