2009-04-03 6 views
2

종료하기 위해 스레드에서 exit(0) (<stdlib.h>)에 대한 호출을 사용하는 .NET C#/C++ 앱이 있습니다..NET - 종결 자 및 종료 (0)

경우에 따라 이상한 부분은 exit을 호출 한 직후 관리 대상 개체의 종료자를 호출하며, 다른 경우에는 전혀 호출되지 않습니다.

상황이 꽤 결정적입니다. 앱이 평생 동안 외부 플러그인 dll (관리되지 않는 C로 작성 됨)에서 일부 메소드를 호출합니다.
dll을 사용하면 finalizer가 항상 호출됩니다.
dll B를 사용하면 finalizers가 호출되지 않습니다.

종료 (0) 호출의 경우 종료 자로 예상되는 동작은 무엇입니까? (예상되는 동작 및 문서화 된 동작이있는 경우)

외부 DLL에 대한 호출이 프로세스가 종료되는 방식에 영향을 줄 수있는 일부 전역 설정을 변경할 수 있습니까?

+0

finalizers보다는 IDisposable 패턴을 사용해야합니다. –

+0

나는 코드를 처음 보았을 때 생각했다.하지만 코드베이스에 악마가 이미있다. ... –

답변

3

크리스 Brumme는 파이 나라가 프로세스를 종료하는 동안 처리하는 방법에 대해 이야기 :

최종 줄은 종료시 실행되는 finalizer에 대한 보장 방법이 거의없는 것 같지만 DLL이 다른 방식으로 작동하도록 할 수 있는지 잘 모르겠습니다. DLL이 DLL_PROCESS_DETACH 처리에서 뭔가를하고있어 .NET에 파이널 라이저를 처리 할 수있는 기회를줍니다.

이 기사는 .NET 1.x 용입니다. .NET 2.0에서이 중 얼마나 많은 부분이 변경되었는지 모르겠습니다. 나중에

3

제프 리히터 (Jeff Richter)의 저서에 따르면이 시스템은 프로세스 종료시 finalizer를 호출하려고 시도하지만 finalizer (2 초)와 total-finalization 40s)이 프로세스를 처리하는 시간 초과 후 프로세스가 중단됩니다. (물론 정확한 시간은 2.0으로 바뀌었을 것입니다.

2 초 이상 걸리는 파이널 라이저를 볼 수 있습니까? 최종 결정이 중단됩니다.

+0

나는 또한 책 (3'rd edition)에 어떤 페이지가 있나? –

2

궁극적으로 이것은 "군비 경쟁"문제입니다. 누군가가 마이크로 소프트에서 어떤 불쾌한 코드가 프로세스를 종료 할 때 파이널 라이저가 실행되지 않는다고 불평하는 버그를 기록합니다. 그래서 문제가 해결됩니다. 그런 다음 누군가가 종료 프로세스를 즉시 종료하여 강제 종료자가 실행되지 않도록하는 방법이없는 것처럼 보이는 버그를 기록하여 Microsoft는이를 다시 허용하는 새로운 API를 추가합니다. 그래서 다른 사람은 새로운 종류의 출구에 반응하여 항상 실행되는 새로운 종류의 "중요"종결자를 요구합니다.

그래서 C++ 코드를 변경하는 것이 현재 군비 경쟁에서 승리하고있는 사람에게 의존하는 것보다 쉽습니다.

+2

TerminateProcess (GetCurrentProcess())는 파이널 라이저 또는 되감기 스택을 실행하지 않도록 보장됩니다 (기본 메소드 - P/Invoke 둘 다). – Joshua

1

finalizers에 넣는 코드가 중요하면 Dispose로 이동하고 Dispose에 if (! placed) 패턴을 사용하여 finalizer에서 Dispose를 호출하십시오.

내 책에서는 파이널 라이저를 런타임에 호출해서는 안됩니다. Dispose는 명시 적이며 훨씬 더 세밀하고 결정적으로 제어 할 수 있습니다.