Using background threads for long processes in MFC: Background Thread 1
We add another button to the dialog:
void CBgthreadDlg::OnBackground()
{
// Run on a background thread. Don't wait for the thread to exit.
TaskThread t;
t.Start();
}
This uses the code from here to implement the thread class:
class TaskThread : public Thread
{
public:
virtual unsigned Run()
{
Task task(NULL);
task.Run();
return 0;
}
};
The source so far: bgthread_source2.zip.
This works fine: the task is run on the background thread, making the dialog totally reponsive to the user. It has several of its own problems:
- There’s no indication that it’s doing anything – we want to report progress to the user, but still have a responsive application.
- The user can spawn multiple background threads. Depending on your application, this might be fine. We’ll assume for the moment that it’s not.
- If the user closes the dialog, the application terminates the background thread with extreme prejudice.
More than that, however, there’s a problem with stability: About 80% of the time, the thread fails to start, failing with an access violation or a pure virtual function call.
This is caused by the destructor for TaskThread being called from the CBgthreadDlg::OnBackground()
function before the
background thread has had a chance to call the virtual Run
function from StaticThreadRoutine
.
We can fix this by allocating the thread object on the heap, rather than the stack. It’s then necessary to clean up the thread object properly, otherwise we get a memory leak. We’ll deal with this in the next post.