簡體   English   中英

對話關閉時應用程序崩潰,線程正在運行

[英]Application crashes on dialogue close with threads running

在我的應用程序中,我有一個模式對話框,其中包含大約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;
    }
}

有什么問題 還是我需要使用更好的方法?

線程同步通常是使用事件完成的。

// 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;
}

CloseHandle不會終止線程。 您可以調用TerminateThread但這不是最好的選擇。

正常的做法是為您的線程提供一個手動重置的事件對象,該對象表示正在關閉。 有時最好有一個標志,以便線程可以中止冗長的操作。 線程照常進行工作,每當它們必須等待某個對象時,您就在該等待中包括shutdown事件對象。

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

  1. 設置關機標志
  2. 發出關機事件信號
  3. 恢復所有線程(如果任何線程被掛起)
  4. 所有線程句柄上的WaitForMultipleObjects ,具有適當的超時
  5. 在超時時間內未退出的任何線程上調用TerminateThread
  6. 關閉所有線程句柄
  7. 銷毀關機事件

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

作為paddy所描述的另一種選擇,它可以代替20條線程來加載組合框,而只需要加載一個線程。 通過擁有20個線程,您可能無法始終加快速度,具體取決於您的數據庫庫。

然后,當該線程定期加載時(例如在每個復選框之間),請檢查用戶是否按下了cancel,如果是,則停止處理並退出線程。

這將使處理不如管理20個線程恕我直言。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM