WAQ
WAQ

Reputation: 2626

Application crashes on dialogue close with threads running

In my application I have a modal dialog which contains about 20 different combo boxes which are bind to certain fields in the databases. The database is huge and on the loading of dialog I have to load all the combo boxes from the databases. So I setup 20 threads (1 each for every combo box).

Everything works fine, but the problem only occurs when the user closes the dialog with close or cancel button or OK button while the threads are running; in that case the application crashes.

I have tried to terminate the threads prematurely as well but that does not help. Here is the thread termination code

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

What is the issue? Or do I need to use a better approach?

Upvotes: 0

Views: 1221

Answers (3)

TheSteve
TheSteve

Reputation: 1158

Synchronizing threads is generally done using events.

// Before Creating threads
HANDLE hEndEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
// Pass handle to threads

Then on termination

SetEvent(hEndEvent);
WaitForMultipleObjects(m_iTotalThreads,m_threads,TRUE,INFINITE); // Wait for all threads to end

// Loop through and close all the thread handles

Note that you need to be occasionally looking for the end event to be set otherwise your threads won't end.

// In Thread
if (WaitForSingleObject(hEndEvent,0)==WAIT_OBJECT_0) {
    // Clean up
    return 0;
}

Upvotes: 1

AndersK
AndersK

Reputation: 36082

As an alternative to what paddy describes another approach would be to instead of having 20 threads that load the comboboxes to just have one thread that loads. By having 20 threads you may not be speeding up things anyway depending on your database library.

Then when that thread is loading periodically (like between each checkbox) check whether user pressed cancel or not, if so then stop processing and exit the thread.

This would make the handling less complicated than managing 20 threads IMHO.

Upvotes: 1

paddy
paddy

Reputation: 63471

CloseHandle does not terminate the thread. You can call TerminateThread but it's not the nicest thing to do...

What is normal is to provide your threads with a manual-reset event object that signals a shutdown is taking place. Sometimes it's also good to have a flag so that threads can abort lenghty operations. The threads carry on their work as usual, and whenever they have to wait on some object, you include the shutdown event object in that wait.

So the procedure on exit is normally to do this:

  1. Set the shutdown flag
  2. Signal the shutdown event
  3. Resume all threads (in case any are suspended)
  4. WaitForMultipleObjects on all thread handles, with an appropriate timeout
  5. Call TerminateThread on any threads that did not exit within the timeout
  6. Close all thread handles
  7. Destroy the shutdown event

This approach requires that threads are created with _beginthreadex, so that you are responsible for closing the handles. The benefit of this is that you can wait on threads, even after they've exited (of course an exited thread is already in the signaled state).

Upvotes: 1

Related Questions