Verwalteter Code nach Thread-Zustandszerstörung in .NET 9 und .NET 10
Auf .NET 9.0.5 und später (einschließlich .NET 10) beendet eine Anwendung, die IronPDF verwendet, mit einem schwerwiegenden Assertion Error und Exit-Code 127.
Attempt to execute managed code after the .NET runtime thread state has been destroyed.
Microsoft hat strengere FLS (Fiber Local Storage) Thread-Bereinigung in .NET 9.0.5 eingeführt. Das Betriebssystem steuert die Reihenfolge der FLS-Callback-Ausführung, die den CLR-Abriss auslösen kann, bevor IronPDF's Chrome-Renderer seine eigene Abschaltsequenz abschließt. Dieses Problem ist Windows-spezifisch; Linux und macOS sind nicht betroffen. .NET 6, 7 und 8 beenden sauber. IronPDF's PDF-Generierung wird erfolgreich abgeschlossen, bevor der Assertion-Fehler auftritt. Microsoft hat das Problem als "Future" erfasst, ohne geplantem Fixdatum.
Optionen
Option 1: Downgrade zu .NET 8 (Empfohlen)
.NET 6.0.36 und .NET 8.0.26 beenden sauber. Downgraden Sie das Ziel-Framework, wenn ein sauberer Prozessabschluss erforderlich ist.
Option 2: Verwenden Sie Testergebnisdateien anstelle von Exit-Codes im CI/CD
Die PDF-Arbeit wird erfolgreich abgeschlossen, bevor der Assertion-Fehler auftritt. Veröffentlichen Sie Testergebnisse aus Ergebnisdateien anstatt sich auf Exit-Codes zu verlassen:
Azure DevOps:
- script: dotnet test --logger "trx" || true
- task: PublishTestResults@2
inputs:
testResultsFiles: '**/*.trx'
- script: dotnet test --logger "trx" || true
- task: PublishTestResults@2
inputs:
testResultsFiles: '**/*.trx'
GitHub Actions:
- run: dotnet test --logger "trx" || true
- uses: dorny/test-reporter@v1
with:
path: '**/*.trx'
reporter: dotnet-trx
- run: dotnet test --logger "trx" || true
- uses: dorny/test-reporter@v1
with:
path: '**/*.trx'
reporter: dotnet-trx
Option 3: Exit-Code im Shell filtern
dotnet run 2>stderr.log; EXIT=$?
if grep -q "thread state has been destroyed" stderr.log; then exit 0; else exit $EXIT; fi
dotnet run 2>stderr.log; EXIT=$?
if grep -q "thread state has been destroyed" stderr.log; then exit 0; else exit $EXIT; fi
Bekannte nicht funktionierende Abhilfen: Installation.SkipShutdown = true, SetErrorMode, Environment.Exit(0) und manuelle GC-Sammlung vor dem Beenden.

