2012-08-09 2 views
0

내 응용 프로그램에 데이터베이스의 특정 필드에 바인딩되는 약 20 개의 다른 콤보 상자가 포함 된 모달 대화 상자가 있습니다. 데이터베이스가 크고 대화 상자를로드 할 때 데이터베이스에서 모든 콤보 상자를로드해야합니다. 그래서 20 개의 스레드를 설정했습니다 (모든 콤보 상자마다 1 개씩). 모든 것은 잘 작동하지만 스레드가 실행되는 동안 사용자가 닫기 또는 취소 버튼 또는 확인 버튼을 사용하여 대화 상자를 닫을 때만 문제가 발생합니다. 이 경우 응용 프로그램이 충돌합니다. 스레드를 너무 일찍 종료하려고 시도했지만 도움이되지 않습니다. 여기 스레드 종료 코드응용 프로그램이 실행 중 스레드가 닫힌 상태에서 닫힘

if(m_iNoOfThreadsCompleted != m_iTotalThreads)  
{ 
     for(int i = 0; i < m_iTotalThreads - 1; i++) 
    { 
      if (m_threads[i] != NULL) 
     { 
      GetExitCodeThread(m_threads[i]->m_hThread, &exit_code); 
      if(exit_code == STILL_ACTIVE) 
       CloseHandle(m_threads[i]->m_hThread); 
     } 
     if(m_iNoOfThreadsCompleted == m_iTotalThreads) 
      break; 
    } 
} 

무엇이 문제입니까? 아니면 더 나은 접근 방법을 사용해야합니까? 도와주세요

답변

0

스레드 동기화는 일반적으로 이벤트를 사용하여 수행됩니다. 종료에 그런

// Before Creating threads 
HANDLE hEndEvent = CreateEvent(NULL,FALSE,FALSE,NULL); 
// Pass handle to threads 

SetEvent(hEndEvent); 
WaitForMultipleObjects(m_iTotalThreads,m_threads,TRUE,INFINITE); // Wait for all threads to end 

// Loop through and close all the thread handles 

편집 : 나는 가끔 그렇지 않으면 스레드가 종료되지 않습니다 설정할 수 종료 이벤트를보고 할 필요가 있음을 언급하는 것을 잊었다.

// In Thread 
if (WaitForSingleObject(hEndEvent,0)==WAIT_OBJECT_0) { 
    // Clean up 
    return 0; 
} 
+0

approch를 사용해 보았지만 여전히 내 응용 프로그램이 충돌합니다. OnDestroy 이벤트에서 이벤트를 설정하고 있습니다. 따라서 OnDestroy가 호출되면 스레드 기능이 작동하지 않습니다. 이 코드를 넣을 수있는 다른 이벤트 처리기가 있습니까? P.S : 버튼 뒤에 코드를 삽입하지 않거나 주 대화 상자가 닫혀 있어도 대화 상자가 모덜리스이므로 내 대화 상자/응용 프로그램을 정상적으로 닫아야합니다. – WAQ

0

CloseHandle 스레드를 종료하지 않습니다. TerminateThread으로 전화 할 수 있지만 가장 좋은 방법은 아닙니다.

정상적인 현상은 종료가 발생했다는 신호를 보내는 수동 재설정 이벤트 개체를 스레드에 제공하는 것입니다. 때때로 스레드가 긴 작업을 중단 할 수 있도록 플래그를 갖는 것이 좋습니다. 스레드는 평상시대로 작업을 수행하며 객체가있을 때마다 기다려야 할 때마다 해당 대기 시간에 종료 이벤트 객체를 포함시킵니다.

그래서 종료의 절차는이 작업을 수행하는 일반적입니다 :

  1. 설정 종료 플래그
  2. 신호 종료 이벤트
  3. 재개 (일시 중단 어떤 경우) 모든 스레드
  4. WaitForMultipleObjects에 적절한 시간 초과를 가진 모든 스레드 핸들
  5. 제한 시간 내에 종료되지 않은 스레드에서 TerminateThread을 호출하십시오.
  6. 닫기 모든 스레드는
  7. 이 방법을 사용하면 핸들을 닫는에 대한 책임이 있습니다 있도록 스레드, _beginthreadex로 생성되어 있어야합니다 종료 이벤트

를 파괴 처리합니다. 이점은 스레드가 종료 된 후에도 스레드를 기다릴 수 있다는 것입니다 (물론 종료 된 스레드는 이미 신호를받은 상태 임).

0

패디가 다른 방법을 설명하는 대신,로드하는 스레드가 하나 뿐이도록 콤보 상자를로드하는 20 개의 스레드가 있어야합니다. 20 개의 스레드를 가짐으로써 데이터베이스 라이브러리에 따라 속도가 향상되지 않을 수도 있습니다.

그런 다음 스레드가 주기적으로로드 될 때 (각 체크 상자 사이와 같이) 사용자가 취소를 눌렀는지 확인하십시오. 그렇다면 처리를 중지하고 스레드를 종료하십시오.

이렇게하면 20 스레드 IMHO를 관리하는 것보다 처리가 덜 복잡해집니다.

관련 문제