My skills at using MFC (MSVC 2008) and threading are basic at best, so combine the two and what do I get? A problem!
Here's my setup. I make a new MFC dialog-based application. I add a List Box to the dialog and make it a control vairbale, which gives me a CListBox member variable through which I can control the List Box. In the ::OnInitDialog() method, I 'new' an object of my own making which I've called 'ThreadObject'. This class spawns a new thread during construction and kills the thread during destruction. I also pass to ThreadObject a pointer to the CListBox member during construction. Only the ThreadObject uses the List Box, so (I would think) threading shouldn't be an issue with it (but I think this is the root of my problem, somehow).
Everything appears to work fine at first. In the spawned thread of the ThreadObject object, I use the List Box to print messages. No problem. However, when I go to delete the ThreadObject (through a button press for now) and stop the thread, everything hangs and I can't figure out why. Here's the source:
// CTestDlg.h
//...
public:
CListBox m_ListBox;
ThreadObject* m_pThreadObject;
afx_msg void OnBnClickedKillThread();
//...
// CTestDlg.cpp
BOOL CTestDlg::OnInitDialog()
{
//...
m_pThreadObject = new ThreadObject(&m_ListBox);
}
void CTestDlg::OnBnClickedKillThread()
{
delete m_pThreadObject;
}
// ThreadObject.h
#ifndef INC_THREAD_OBJECT_H
#define INC_THREAD_OBJECT_H
class ThreadObject
{
public:
ThreadObject(CListBox* pListBox);
~ThreadObject();
void ThreadObjectThread();
private:
HANDLE m_Thread;
DWORD m_ThreadID;
volatile bool m_bThreadRun;
CListBox* m_pListBox;
};
#endif // INC_THREAD_OBJECT_H
// ThreadObject.cpp
#include "stdafx.h"
#include "ThreadObject.h"
DWORD WINAPI ThreadProc(void* param);
// Constructor
ThreadObject::ThreadObject(CListBox* pListBox)
: m_bThreadRun(true),
m_Thread(NULL),
m_pListBox(pListBox)
{
m_Thread = CreateThread(NULL, 0, ThreadProc, this, 0, &m_ThreadID);
}
// Destructor
ThreadObject::~ThreadObject()
{
m_bThreadRun = false;
WaitForSingleObject(m_Thread, INFINITE);
CloseHandle(m_Thread);
}
// WINAPI thread entry point
DWORD WINAPI ThreadProc(void* param)
{
ThreadObject* pThreadObject = reinterpret_cast<ThreadObject*>(param);
pThreadObject->ThreadObjectThread();
return 0;
}
// ThreadObject thread entry point
void ThreadObject::ThreadObjectThread()
{
while (m_bThreadRun)
{
Sleep(1000);
m_pListBox->InsertString(0, L"Tick");
}
}
When I start this up and run, "Tick" gets inserted to the list box about every 1 second as expected. No problem. But when I click the Kill Thread button which deletes the pointer to the ThreadObject and ~ThreadObject gets called, bad things happen.
m_bThreadRun is set to false and the thread seems to exit just fine, but I never return from the WaitForSingleObject() call and I don't know why.