highlander141
highlander141

Reputation: 1725

Handle async callback in MFC GUI application running in main thread from a worker thread

There is an MFC GUI app which on button click event, tries to connect to HTTP server and gets back info and update in the UI.

First I tried to create an std::async task to run this in a new thread. But it was blocking on the get() call.

Here is the sample OnBtnClick() event.

THREADSTRUCT *_param = new THREADSTRUCT;
_param->_this = this;
AfxBeginThread(StartThread, _param);

I am able to make the GUI non-blocking as every button click triggers new thread and contacts server. And in that worker_thread I am able to wait on the std::future and get back the result. But the real issue is how to transfer this result to the main thread from worker thread?

Upvotes: 0

Views: 67

Answers (1)

Constantine Georgiou
Constantine Georgiou

Reputation: 3401

A quite common way to implement this is to Post (asynchronously) a custom message to a window (owned by the UI thread), when the worker thread completes and has retrieved some data. The data can be put in the message parameters, eg a pointer (memory block) in the LPARAM parameter. The UI thread can store or display the data. See an example here.

In the MFC application you will have to define a custom message (WM_APP + nnnn) and an ON_MESSAGE handler in the message-map of a window class. For example:

#define CM_HTTPSERVERNOTIFY (WM_APP + 581)

ON_MESSAGE(CM_HTTPSERVERNOTIFY, OnHttpServerNotify)

// CM_HTTPSERVERNOTIFY message handler
afx_msg LRESULT CMyView::OnHttpServerNotify(WPARAM wParam, LPARAM lParam)
{
    // Store or display the data here
}

You can move all data-retrieval code into a non-MFC DLL, if you want. There you initiate a thread using the Win32 CreateThread() or the C++ std::async function, returning immediately after creating the thread, without waiting for it to complete. Upon completion the worker thread should notify the UI, by posting a message. PostMessage() is a Win32 function, not MFC (you will have to pass the HWND that will be receiving the notifications). Also, the global memory functions (GlobalAlloc()/GlobalFree()) can be called accross modules of the same process, eg you can allocate a memory block in the DLL and free it in the application, without worrying about heap corruption. Quite as demonstrated in the linked answer.

Upvotes: 0

Related Questions