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

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

4

3 回答 3

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;
}
于 2012-08-09T04:41:37.610 回答
1

CloseHandle不会终止线程。你可以打电话TerminateThread,但这不是最好的做法......

正常情况是为您的线程提供一个手动重置事件对象,该对象表示正在发生关闭。有时最好有一个标志,以便线程可以中止冗长的操作。线程像往常一样继续工作,每当它们必须等待某个对象时,您就会在该等待中包含关闭事件对象。

所以退出的过程通常是这样做的:

  1. 设置关机标志
  2. 发出关闭事件信号
  3. 恢复所有线程(以防任何线程被挂起)
  4. WaitForMultipleObjects在所有线程句柄上,具有适当的超时
  5. 调用TerminateThread未在超时内退出的任何线程
  6. 关闭所有线程句柄
  7. 销毁关闭事件

这种方法要求使用创建线程_beginthreadex,以便您负责关闭句柄。这样做的好处是您可以等待线程,即使它们已经退出(当然退出的线程已经处于信号状态)。

于 2012-08-09T04:46:11.047 回答
1

作为 paddy 描述的另一种方法的替代方法是,不是让 20 个线程加载组合框,而是只有一个线程可以加载。通过拥有 20 个线程,您可能无法加快速度,具体取决于您的数据库库。

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

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

于 2012-08-09T04:51:45.323 回答