2012-08-09 171 views
0

在我的應用程序中,我有一個模式對話框,其中包含約20個不同的組合框,這些組合框綁定到數據庫中的某些字段。數據庫非常龐大,在加載對話框時我必須加載數據庫中的所有組合框。所以我設置了20個線程(每個組合框1個)。每件事情都可以正常工作,但只有當用戶在線程運行時用關閉或取消按鈕或OK按鈕關閉對話框時纔會出現問題。在這種情況下,應用程序崩潰。 我試圖過早地終止線程,但這並沒有幫助。這裏線程終止代碼應用程序在運行線程關閉時崩潰

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 2012-08-10 09:44:04

0

CloseHandle不終止該線程。您可以撥打電話TerminateThread,但這不是最好的事情...

什麼是正常的是爲您的線程提供一個手動重置事件對象,表示正在發生關機。有時候也可以有一個標誌,以便線程可以中止長時間的操作。這些線程像平常一樣繼續工作,並且每當它們必須等待某個對象時,都會在該等待中包含關閉事件對象。

因此在退出的過程通常是這樣做:

  1. 設置關機標誌
  2. 信號關閉事件
  3. 簡歷(任何懸浮的情況下)的所有線程
  4. WaitForMultipleObjects上所有線程句柄,具有適當的超時時間
  5. 在任何未超時的線程上調用TerminateThread
  6. 關閉所有線程處理
  7. 摧毀關閉事件

這種方法要求線程與_beginthreadex創建的,所以你是負責關閉句柄。這樣做的好處是你可以等待線程,即使它們已經退出(當然退出的線程已經處於信號狀態)。

0

作爲稻田描述的另一種方法的替代方法是將20個加載組合框的線程加載到一個線程中。通過擁有20個線程,您可能無法加快速度,這取決於您的數據庫庫。

然後,當該線程週期性加載(如每個複選框之間)檢查用戶是否按下取消或不,如果是,則停止處理並退出線程。

這會使處理比管理20個線程恕我直言複雜。