应用程序崩溃对话关闭与线程运行

时间:2012-08-09 04:34:15

标签: c++ mfc

在我的应用程序中,我有一个模态对话框,其中包含大约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;
    }
}

问题是什么?或者我需要使用更好的方法吗?

3 个答案:

答案 0 :(得分:1)

通常使用事件来完成同步线程。

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

答案 1 :(得分:1)

CloseHandle不会终止该帖子。你可以致电TerminateThread,但这不是最好的事情......

正常情况是为线程提供一个手动重置事件对象,表示正在关闭。有时候,拥有一个标志也很好,这样线程就可以中止长时间的操作。线程像往常一样继续工作,每当必须等待某个对象时,就会在等待中包含shutdown事件对象。

因此退出程序通常是这样做的:

  1. 设置关闭标志
  2. 发出关闭事件信号
  3. 恢复所有线程(如果有任何线程被暂停)
  4. 所有线程句柄上的
  5. WaitForMultipleObjects,具有适当的超时
  6. 在超时
  7. 内未退出的任何线程上调用TerminateThread
  8. 关闭所有线程句柄
  9. 销毁关闭事件
  10. 此方法要求使用_beginthreadex创建线程,以便您负责关闭句柄。这样做的好处是你可以等待线程,即使它们已经退出(当然已退出的线程已经处于信号状态)。

答案 2 :(得分:1)

作为paddy所描述的替代方法,另一种方法是使用20个线程来加载组合框,而只需要加载一个线程。根据您的数据库库,通过拥有20个线程,您可能无法加快速度。

然后当该线程定期加载时(如每个复选框之间)检查用户是否按下取消,如果是,则停止处理并退出该线程。

这将使处理比管理20个线程恕我直言更简单。