Reputation: 1725
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
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