Featured image of post MFC Worker Threads Explored

MFC Worker Threads Explored

MFC Worker Threads Explored

MFC Worker Threads Explored

A Quick History of MFC

Ah, MFC—the Microsoft Foundation Classes.

The framework that let Windows developers in the ‘90s write GUI applications without manually calling the Windows API for every single button, label, and window.

A revolution! A game-changer!

And a magnificent way to write enterprise software that nobody wants to maintain 20 years later.

Back in the ancient days of computing (a.k.a. Windows 3.1), life was simple.

We had Win16, which was a 16-bit, single-tasking, cooperative-multitasking environment.

You know what that means?

NO THREADS!

If you wanted to do something time-consuming, well, tough luck.

Your UI would freeze, users would scream, and you’d be left wondering if there was a better way.

Then came Windows 95 and the glorious transition to Win32—an actual preemptive multitasking environment.

Finally, developers could create background threads to run long operations while keeping the UI responsive.

The problem? Not everyone knew how to use them properly, and a lot of people (like past-you) probably did it wrong a few times before getting it right.

Fast forward a bit, and we had Windows NT, Windows 2000, XP, and beyond, all of which supported real, honest-to-goodness multithreading.

And of course, the cool kids (like me) had to start playing around with worker threads.

Worker Threads in MFC

Once we had Win32, it wasn’t long before Microsoft introduced MFC-based threading mechanisms.

And let me tell you, they had options. Here are the two main types of MFC threads:

  1. Worker Threads – Background threads that perform tasks without UI interaction.
  2. UI Threads – Threads that can create and interact with Windows UI elements.

Most of the time, you’ll be using worker threads because UI threads are a pain unless you really need them.

The Ways to Create Worker Threads in MFC

There are a couple of ways to create worker threads in MFC:

1. Using AfxBeginThread (MFC Style)

MFC provides the AfxBeginThread function, which makes spinning up threads almost painless. Here’s a simple example:

1
2
3
4
5
6
7
8
9
UINT MyWorkerThreadFunction(LPVOID pParam) {
    // Do some time-consuming task here
    Sleep(3000);
    return 0;
}

void StartWorkerThread() {
    CWinThread* pThread = AfxBeginThread(MyWorkerThreadFunction, NULL);
}

Pros:

  • Clean and easy to use.
  • MFC manages cleanup automatically.
  • Plays nicely with MFC’s message pumping system.

Cons:

  • Slightly more overhead than using raw Windows API threads.
  • Limited control over thread creation parameters.

2. Using Windows API Threads (For the Hardcore Devs)

If you’re feeling brave (or just want more control), you can use CreateThread from the Windows API:

1
2
3
4
5
6
7
8
9
DWORD WINAPI MyWinAPIFunction(LPVOID lpParam) {
    Sleep(3000);
    return 0;
}

void StartWinAPIThread() {
    HANDLE hThread = CreateThread(NULL, 0, MyWinAPIFunction, NULL, 0, NULL);
    if (hThread) CloseHandle(hThread);
}

Pros:

  • More control over thread attributes.
  • More lightweight than MFC’s AfxBeginThread.

Cons:

  • YOU are responsible for cleanup (i.e., calling CloseHandle).
  • No MFC integration, so interacting with the UI from this thread is tricky.

3. Using std::thread (Modern C++ Style)

With modern C++, you can use std::thread, which is cleaner and portable:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <thread>

void MyCppThreadFunction() {
    Sleep(3000);
}

void StartCppThread() {
    std::thread t(MyCppThreadFunction);
    t.detach();
}

Pros:

  • Modern and portable.
  • Automatic cleanup if std::jthread (C++20) is used.

Cons:

  • Slightly trickier in MFC applications (you must ensure proper synchronization).

Comparing MFC Threads vs. Windows API Threads

FeatureMFC AfxBeginThreadWindows API CreateThread
Ease of UseEasyHarder
CleanupAutomaticManual (must call CloseHandle)
Integration with MFCYesNo
PerformanceSlightly more overheadMore lightweight
Fine-grained controlNoYes

Conclusion

If you’re working in an MFC-based application, your best bet is to use AfxBeginThread.

It’s easy, clean, and integrates nicely with the rest of MFC.

If you’re working on something more low-level or performance-sensitive, then CreateThread is the way to go, but just remember to clean up your mess.

And if you’re starting fresh with modern C++, then std::thread is a great alternative that will work even outside of Windows.


🔥 Key Ideas

ConceptDescription
Win16No threads, just sadness.
Win32Introduced proper multithreading.
Worker ThreadsBackground tasks without UI.
UI ThreadsCan interact with Windows UI.
AfxBeginThreadThe MFC way to do threads.
CreateThreadThe Windows API way to do threads.
std::threadModern C++ threading.
Thread CleanupDon’t forget to close handles!

📚 References