MTRECALC: Supports Multithread Applications

Click to open or copy the MTRECALC project files.

MTRECALC illustrates Microsoft Foundation Class Library (MFC) support for multithread applications.

MFC distinguishes two types of threads: user interface threads and worker threads. A user interface thread has its own message pump for handling user interface events separately from other threads. A worker thread does not have its own message pump. MTRECALC illustrates a worker thread. The worker thread simulates a lengthy calculation by waiting for a timer before completing the calculation of adding two numbers.

MTRECALC displays a simple form for adding two integers, simulating a spreadsheet that recalculates whenever you update a cell or click Recalculate Now. The result field displays "Recalculating..." during the time MTRECALC is simulating a lengthy calculation. You can change the recalculation time by clicking Speed of Recalculation on the Demo menu.

Click Worker Thread or Single Thread on the Demo menu to compare the “feel” of recalculation in a separate worker thread versus recalculation in the same thread as the main application user interface thread. For example, in the Single Thread demonstration, you cannot access the menus of MTRECALC while it is recalculating, but in the Worker Thread demonstration you can. In the Single Thread demonstration you cannot update either of the integer fields while MTRECALC is recalculating, but in the Worker Thread demonstration you can. If you update a field while the worker thread is already recalculating, the active recalculation will be abandoned and a new one started.

The Kill Worker Thread command on the Demo menu is enabled only while the worker thread is recalculating. If you use the Kill Worker Thread command to interrupt the recalculation before it is done, then the result field displays a question mark ("?"). You can restart the calculation with the Recalculate Now command.

If you attempt to save the MTRECALC document before recalculation has completed, you will be prompted with "Do you wish to wait while recalculation finishes?" If you respond with yes, MTRECALC displays an hourglass while it waits for the recalculation to complete before saving the document. To exercise this demonstration, you will probably need to use the Speed of Recalculation command to increase the recalculation time from the default 5 seconds to 10 or 15 seconds. This will give you enough time to navigate through the File Save menu and dialog.

This sample demonstrates the following keywords:

AfxBeginThread; AfxGetMainWnd; AfxMessageBox; CArchive::IsStoring; CCmdTarget::BeginWaitCursor; CCmdTarget::EndWaitCursor; CCmdUI::Enable; CCmdUI::SetCheck; CDialog::DoModal; CDocument::GetFirstViewPosition; CDocument::GetNextView; CDocument::OnNewDocument; CDocument::OnSaveDocument; CDocument::SetModifiedFlag; CDocument::UpdateAllViews; CFrameWnd::Create; CFrameWnd::DockControlBar; CFrameWnd::EnableDocking; CFrameWnd::LoadFrame; CObject::AssertValid; CObject::Dump; CObject::Serialize; CStatusBar::CommandToIndex; CStatusBar::SetPaneText; CString::Format; CString::LoadString; CView::DoPreparePrinting; CView::GetDocument; CView::OnBeginPrinting; CView::OnEndPrinting; CView::OnPreparePrinting; CView::OnPrint; CView::OnUpdate; CWinApp::AddDocTemplate; CWinApp::Enable3dControls; CWinApp::EnableShellOpen; CWinApp::InitInstance; CWinApp::LoadStdProfileSettings; CWinApp::RegisterShellFileTypes; CWnd::DoDataExchange; CWnd::OnCreate; CWnd::OnKillFocus; CWnd::PostMessage; CWnd::SendMessage; CWnd::SetWindowText; CWnd::ShowWindow; CWnd::UpdateData; CWnd::UpdateWindow; CreateEvent; DragAcceptFiles; GetExitCodeThread; GetVersion; LoadBitmap; PostMessage; ResetEvent; SetEvent; Sleep; WaitForSingleObject