Code managé après destruction de l'état du thread sur .NET 9 et .NET 10
Sur .NET 9.0.5 et versions ultérieures (y compris .NET 10), une application utilisant IronPDF se termine par une erreur d'assertion fatale et un code de sortie 127.
Attempt to execute managed code after the .NET runtime thread state has been destroyed.
Microsoft a introduit un nettoyage plus strict des threads FLS (Fiber Local Storage) dans .NET 9.0.5. Le système d'exploitation contrôle l'ordre d'exécution des rappels FLS, ce qui peut déclencher le démantèlement CLR avant que le moteur de rendu Chrome de IronPDF ne termine sa propre séquence d'arrêt. Ce problème est spécifique à Windows ; Linux et macOS ne sont pas affectés. .NET 6, 7 et 8 se terminent correctement. La génération de PDF de IronPDF se termine avec succès avant le déclenchement de l'assertion. Microsoft a classé le problème comme "Futur" sans date de correctif prévue.
Options
Option 1 : Régresser vers .NET 8 (recommandé)
.NET 6.0.36 et .NET 8.0.26 se terminent correctement. Régressé le framework cible si une sortie de processus propre est requise.
Option 2 : Utiliser des fichiers de résultats de test au lieu de codes de sortie dans CI/CD
Le travail de PDF se termine avec succès avant le déclenchement de l'assertion. Publier les résultats de test à partir de fichiers de résultats plutôt que de s'appuyer sur le code de sortie :
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 : Filtrer le code de sortie dans le shell
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
Atténuations non fonctionnelles connues : Installation.SkipShutdown = true, SetErrorMode, Environment.Exit(0), et collecte manuelle du GC avant de quitter.

