Wednesday, February 09, 2005

Using MFC and threads, dazzled and amazed!?

As always Im amazed on how much worse it is by developing applications in MFC than using Swing. MFC has a complete different view of how a dialog and threads should cooperate. In short words, MFC wont let any threads to change any control in a dialog. WTF? If you have a task that takes hours, and you want to have a GUI that displays the progress of it; what do you do? The thread is not allowed to use any of the GUI controls at all, and if you do, then suddenly the whole application will lock up because you try to change a control. In Swing you dont have this problem, because you have true VMC modelling.


So what do you do when you want to update a GUI from a thread. There are two ways in MFC: you can either change the GUI control youself, but this will result in deadlocks 100% guarantee; you can either change the value (string/dword) behind the control and then call the UpdateData() method. But something that they forgot to say is that you cant call UpdateData() from a thread outside the GUI loop, doing that will result in deadlock 100% guarantee. MS only response is "threads are not allowed to touch GUI, you must send a message to the dialog that you want to update". Fair enough, but MS has failed to give such a functionality and if I want to update a tabbed dialog with data from the thread, there is no way but to implement a WM_USER message listener for every dialog that you want to update from the thread. Sheeeesh, I dont want to put more stuff into each one of the dialogs, for just make it "thread-safe" for the MFC GUI.


My solution to this problem is jsut to create a base CDialog class that will handle this problem, and is safe to update all values in a dialog. It took med 5 minutes to create it and test it. Whoah, that was easy, but that main point is IF IT WAS SO EASY, WHY HASNT MS DONE THIS IN THE FIRST PLACE? Why do I have to live with crap design eons after the MFC was "designed", why can't they extend the dialog class with such functionality so you dont have to sit and wonder why the application has locked. "Is it me or MFC?"


Im still amazed that MFC is still not thread safe, it was earlier one of the most commonly used application tools/API for creating applications. How could it survive for such a long time??


My solution, is as easy as pie. Here it is:

#include

#include



class CRefreshDialog : public CDialog

{

public:

CRefreshDialog(UINT nIDTemplate,CWnd* pParentWnd = NULL );

virtual ~CRefreshDialog();

virtual BOOL OnWndMsg( UINT message,WPARAM wParam, LPARAM lParam, LRESULT* pResult );



void RefreshDialog();

private:

CCriticalSection refreshMutex;

};





#define WM_REFRESH WM_USER + 0x9283



CRefreshDialog::CRefreshDialog(UINT nIDTemplate, CWnd* pParentWnd ) : CDialog(nIDTemplate, pParentWnd)

{

}



CRefreshDialog::~CRefreshDialog()

{

}



BOOL CRefreshDialog::OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult )

{

BOOL wasHandled = FALSE;

if (message == WM_REFRESH)

{

UpdateData(FALSE);

} else

{

wasHandled = CDialog::OnWndMsg(message, wParam, lParam, pResult);

}

return wasHandled;

}



void CRefreshDialog::RefreshDialog()

{

CSingleLock lock(&refreshMutex);

lock.Lock();

::PostMessage(m_hWnd, WM_REFRESH, 0, 0);

lock.Unlock();

}

11 comments:

Anonymous said...

Neither AWT nor Swing are thread-safe either, you need to use invokeLater() whenever you want to do a thread operation. Attempting to access the GUI in a thread other than the event thread will result in a deadlock and/or unpredictable GUI behavior.

This is very common for GUI toolkits, MFC is no worse than any other.

--
Cedric
http://beust.com/weblog

Frank said...

It depends what control you use. Your approach works for simple controls like CStatic, CEdit, etc. However, how can you make UpdateData(FALSE) refresh a CListCtrl or CTreeCtrl with new data?

Frank
frankwwu@hotmail.com

Viagra Online said...

I did my best to read it all but I couldn't. I won't leave this blog yet, but I would like to read it each entry done.

posicionamiento web en buscadores said...

Thanks so much for this post, pretty helpful data.

muebles cadiz said...

I found a great deal of useful material here!

hcg said...

Really great post, Thank you for sharing This knowledge.Excellently written article, if only all bloggers offered the same level of content as you, the internet would be a much better place. Please keep it up!

Pasaran Bola said...

This is the perfect blog for anyone who wants to know about this topic. You know so much its almost hard to argue with you (not that I really would want...HaHa). You definitely put a new spin on a subject thats been written about for years. Great stuff, just great! Bola Tangkas Tangkasnet

Banda Bolar said...

This is a smart blog. I mean it. You have so much knowledge about this issue, and so much passion. You also know how to make people rally behind it, obviously from the responses. Youve got a design here thats not too flashy, but makes a statement as big as what youre saying. Great job, indeed. Ibcbet Bola Tangkas

Taruhan Online said...

Thanks combination of suitable and useful information and well-written sentences that will certainly entice your sense.There are so multiple comments here that are really entertaining and conducive to me thanks for sharing a link especially for sharing this blog. Judi Bola Online

kholilatun nikmah said...

Download opera mini
Download Mozilla Firefox
Download avast antivirus
Download smadav terbaru
Daftar Harga Smartfren Terlengkap
Daftar Harga Samsung Galaxy
Spesifikasi Xiaomi Redmi s1
Contoh surat izin sekolah
Contoh surat terbaru
Harga hape terbaru
Terbaru Terbaik

Online GED Courses said...

great work has done thanks for sharing and keep it up