应用程序在运行线程关闭时崩溃

应用程序在运行线程关闭时崩溃

问题描述:

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

问题是什么。或者我需要使用更好的方法?请帮助

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

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

CloseHandle不终止该线程。您可以拨打电话TerminateThread,但这不是最好的事情...

什么是正常的是为您的线程提供一个手动重置事件对象,表示正在发生关机。有时候也可以有一个标志,以便线程可以中止长时间的操作。这些线程像平常一样继续工作,并且每当它们必须等待某个对象时,都会在该等待中包含关闭事件对象。

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

  1. 设置关机标志
  2. 信号关闭事件
  3. 简历(任何悬浮的情况下)的所有线程
  4. WaitForMultipleObjects上所有线程句柄,具有适当的超时时间
  5. 在任何未超时的线程上调用TerminateThread
  6. 关闭所有线程处理
  7. 摧毁关闭事件

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

作为稻田描述的另一种方法的替代方法是将20个加载组合框的线程加载到一个线程中。通过拥有20个线程,您可能无法加快速度,这取决于您的数据库库。

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

这会使处理比管理20个线程恕我直言复杂。