应用程序在运行线程关闭时崩溃
问题描述:
在我的应用程序中,我有一个模式对话框,其中包含约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;
}
答
CloseHandle
不终止该线程。您可以拨打电话TerminateThread
,但这不是最好的事情...
什么是正常的是为您的线程提供一个手动重置事件对象,表示正在发生关机。有时候也可以有一个标志,以便线程可以中止长时间的操作。这些线程像平常一样继续工作,并且每当它们必须等待某个对象时,都会在该等待中包含关闭事件对象。
因此在退出的过程通常是这样做:
- 设置关机标志
- 信号关闭事件
- 简历(任何悬浮的情况下)的所有线程
-
WaitForMultipleObjects
上所有线程句柄,具有适当的超时时间 - 在任何未超时的线程上调用
TerminateThread
- 关闭所有线程处理
- 摧毁关闭事件
这种方法要求线程与_beginthreadex
创建的,所以你是负责关闭句柄。这样做的好处是你可以等待线程,即使它们已经退出(当然退出的线程已经处于信号状态)。
答
作为稻田描述的另一种方法的替代方法是将20个加载组合框的线程加载到一个线程中。通过拥有20个线程,您可能无法加快速度,这取决于您的数据库库。
然后,当该线程周期性加载(如每个复选框之间)检查用户是否按下取消或不,如果是,则停止处理并退出线程。
这会使处理比管理20个线程恕我直言复杂。
我尝试使用approch,但仍然我的应用程序崩溃。我在OnDestroy事件上设置事件。所以一旦OnDestroy被调用,我的线程函数就不会被命中。有没有其他的事件处理程序,我可以把这个代码? P.S:我没有把代码放在按钮后面,因为我的对话框是非模态的,所以即使主应用程序关闭我的对话框/应用程序也应该优雅地关闭。 – WAQ 2012-08-10 09:44:04