2010-04-23 6 views
2

우리는 다중 스레드가 많은 WinForms 데스크탑 응용 프로그램을 가지고 있습니다. 3 스레드는 Application.Run 및 다른 백그라운드 작업자 스레드와 함께 실행됩니다. 모든 스레드를 제대로 종료하는 것은 다소 까다 롭습니다.하지만 마침내 제대로 된 것으로 생각했습니다.0 스레드로 응용 프로그램이 종료되지 않습니다.

하지만 실제로 응용 프로그램을 배포 할 때 사용자는 응용 프로그램을 종료하지 않고 시작했습니다. System.Threading.Mutex가 응용 프로그램을 여러 번 실행하지 못하도록하기 때문에 작업 관리자로 가서 이전 프로그램을 다시 실행해야만 다시 실행할 수 있습니다.

모든 스레드는 주 스레드가 종료되기 전에 Thread.Join을 가져오고, 스폰하는 각 스레드에 로깅을 추가했습니다. 로그에 따라 시작되는 모든 단일 스레드도 종료되고 주 스레드도 종료됩니다. 낯선 사람, 실행중인 SysInternals ProcessExplorer도 응용 프로그램이 종료 될 때 모든 스레드가 사라지는 것을 보여줍니다. 에서와 같이 스레드가 0 개 (관리 또는 비 관리)이지만 프로세스가 아직 실행 중입니다.

개발자 컴퓨터 나 테스트 환경에서이를 재현 할 수 없으며 Windows XP (Vista 또는 Windows 7 또는 Windows Server 제외)에서만 발생합니다. 0 스레드로 프로세스를 계속 실행하려면 어떻게해야합니까?

편집 :

다음은 좀 더 자세히 설명합니다. 이벤트 루프 중 하나는 COM 개체를 사용하여 장치 드라이버와 통신하는 Win32 interop DLL을 호스팅하는 것입니다. 장치 드라이버가 시간에 민감하기 때문에 UI 스레드가 상당한 시간 (예 : 데이터베이스 호출이 끝날 때까지 대기) 동안 차단 될 때마다 장치 드라이버를 방해하게됩니다.

그래서 주 스레드가 장치 드라이버 스레드로 Thread.Join을 수행하도록 코드를 변경했습니다. 실제로 응용 프로그램이 잠기 게되었습니다 ... Join이 완료된 후 UI 스레드에서 몇 가지 호출을 기록한 다음 모든 것이 중지됩니다. 장치의 전원이 꺼지면 드라이버가 절대로 시작되지 않고 문제가 사라집니다. 따라서 드라이버가 종료 된 후에도 응용 프로그램을 유지해야하는 책임이 드라이버에있는 것처럼 보입니다.

+0

확인이 ..., 내가 줄 수있는 모든 답변입니다.com/oldnewthing/archive/2004/07/23/192531.aspx –

+0

재미있는 시나리오이지만 상황과 일치하지 않습니다. 이 프로세스는 작업 관리자를 통해 사용자가 완전히 종료 할 수 있습니다. 우리는 1/2 시간 동안 그것을 달리게했다. –

+0

정확히 0 개의 스레드가 있는지 확인하는 이유는 무엇입니까? 디버거로 이것을 테스트 해 보셨습니까? Windows XP 작업 관리자조차 스레드 수를 표시 할 수 있습니다 (단,이 열을 메뉴>보기> 열 선택 ...을 통해 프로세스 탭에 명시 적으로 추가해야 함). 실제로 스레드가 없다는 것은 의심 스럽습니다. 내 첫 번째 아이디어는 출구/정리 과정에서 교착 상태가 될 수 있습니다. – SergGr

답변

0

우리는 루트 프로그램 원인을 파악 결코하지 않았다, 그러나 그것은 문제를 해결 새 드라이버로 문제 및 업그레이드를 발생하는 특정 드라이버 버전이었다. HTTP : //blogs.msdn 다른 사람이 언젠가는 비슷한 문제로 실행되는 경우

불행하게도,이

0

Application.Run 호출의 자식이 종료되지 않았습니까? 또한 실제로 응용 프로그램이 종료되는 원인 - 모든 스레드가 종료되면 자동으로 닫힙니 다 (자동으로 사용자가 코드를 작성하여이를 의미 함), 또는 사용자가 모방합니까?

"스레드 완료"이벤트 코드에서 경쟁 조건이 발생하여 문제가 발생하는 경우가 있습니다. 마지막 두 스레드는 동시에 종료되고 이벤트를 동시에 발생 시키며 각 이벤트는 마지막 스레드가 아니라고 결정할 것이므로 스레드 수가 0 인 경우에도 응용 프로그램이 계속 실행됩니다. 이 문제를 해결하기 위해 경쟁 조건을 찾아 제거 할 수 있었지만 매 초 또는 두 번씩 검사하고 스레드 수를 얻는 타이머를 사용할 수도 있습니다. 아직 열려 있지 않으면 응용 프로그램을 종료합니다.

+0

Application.Run 호출은 주 스레드에서 Application.Exit()에 의해 종료됩니다. 주 스레드가 종료되기 전에 다른 Application.Run() 호출을 종료하려고 시도합니다. –

관련 문제