Zarzadzany kod po zniszczeniu stanu watku w .NET 9 i .NET 10
W .NET 9.0.5 i pozniejszych (w tym .NET 10), aplikacja korzystajaca z IronPDF konczy dzialanie z krytycznym bledem weryfikacji i kodem wyjscia 127.
Attempt to execute managed code after the .NET runtime thread state has been destroyed.
Firma Microsoft wprowadzila surowsze czyszczenie watkow FLS (Fiber Local Storage) w .NET 9.0.5. System operacyjny kontroluje kolejnosc wykonywania wywolan zwrotnych FLS, co moze wywolywac likwidacje CLR przed zakonczeniem wlasnej sekwencji zamkniecia przez render IronPDF w Chrome. Problem ten dotyczy tylko systemu Windows; Linux i macOS nie sa dotkniete. .NET 6, 7 i 8 koncza dzialanie bez problemow. Generowanie plikow PDF przez IronPDF konczy sie pomyslnie przed wystapieniem bledu weryfikacji. Microsoft zaklasyfikowal ten problem jako "Przyszlosc" bez planowanej daty naprawy.
Opcje
Opcja 1: Przejdz na .NET 8 (Zalecane)
.NET 6.0.36 i .NET 8.0.26 koncza dzialanie bez problemow. Przejdz na starsza wersje docelowego frameworku, jesli wymagane jest czyste zakonczenie procesu.
Opcja 2: Uzywaj plikow z wynikami testow zamiast kodow wyjscia w CI/CD
Praca nad PDF konczy sie pomyslnie przed wystapieniem bledu weryfikacji. Publikuj wyniki testow z plikow wynikowych zamiast polegac na kodzie wyjscia:
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
Opcja 3: Filtruj kod wyjscia w powloce
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
Znane nieskuteczne środki zaradcze: Installation.SkipShutdown = true, SetErrorMode, Environment.Exit(0) i ręczne zbieranie GC przed zakończeniem.

