ASSERT_VALID error when passing the MFC window class pointer in multiple threads

Source: Internet
Author: User
In multi-threaded design, many people send the pointer of the dialog box class or other classes to the working thread to save trouble, and call the member functions or member variables of the class in the working thread.
However, in the Debug version, in some cases, especially when pWnd-> UpdateData (FALSE) is called in the work thread, an error occurs.
The cause of this error has been mentioned in many places on the Internet. However, it is disappointing that a few articles have to be mentioned about the thread module status or something, people can see the cloud in the fog (however, to be honest, that is, they only know from these articles What Is Going On ).

As a matter of fact, I think it is very simple to avoid multi-thread conflicts. The following is an example:

There is an edit box and a button in your dialog box class. The edit box is associated with the variable m_strText.

When you press the button, you have the following code:
M_strText = "Hello ";
UpdateData (FALSE );

Normally, "Hello" is displayed in your editing box.
However, if you are not afraid of 10 thousand, you are afraid that your thread will be switched after you execute the m_strText = "Hello" code, but in your working thread, you set m_strText to "Sorry". As a result, when the thread switches back, after UpdateData (FALSE), the edit box is changed to "Sorry" instead of "Hello.

Therefore, MFC does not recommend passing the pointer of the MFC object in this multi-thread mode, and the MFC manually adds an ASSERT_VALID to indicate that they are not recommended.

However, it is not recommended that the thread cannot be used. If you can confirm that your thread will not conflict with each other, you can use it boldly.
Because of this, the problem of ASSERT_VALID exists only in the Debug version, but not in the Release version, because it has no reason to stop us from using it.

Even so, after all, we need to use the Debug version for debugging many times. Such an approach of MFC still changes a lot. Fortunately, MFC makes the code of the actual detection thread-related MFC object into a virtual function. That is to say, we can reload it so that this problem will not occur during debugging.

Next, let's warmly welcome the appearance of the leading role --Virtual VoidCObject ::AssertValid ( ) Const;

ASSERT_VALID will finally call the AssertValid function of the MFC class object. Therefore, as long as the AssertValid is reloaded, it will not pop up error boxes (in fact, these error boxes, ).

Let's not talk about it. Suppose our dialog box is CTmthDlg. below is the code after heavy load.

Void CTmthDlg: AssertValid () const
{
If (m_hWnd = NULL)
Return; // null (unattached) windows are valid

// Check for special wnd ??? Values
ASSERT (HWND_TOP = NULL); // same as desktop
If (m_hWnd = HWND_BOTTOM)
ASSERT (this = & CWnd: wndBottom );
Else if (m_hWnd = HWND_TOPMOST)
ASSERT (this = & CWnd: wndTopMost );
Else if (m_hWnd = HWND_NOTOPMOST)
ASSERT (this = & CWnd: wndNoTopMost );
Else
{
// Shocould be a normal window
ASSERT (: IsWindow (m_hWnd ));

// Shocould also be in the permanent or temporary handle map
/* CHandleMap * pMap = afxMapHWND ();
ASSERT (pMap! = NULL );

CObject * p;
ASSERT (p = pMap-> LookupPermanent (m_hWnd ))! = NULL |
(P = pMap-> LookupTemporary (m_hWnd ))! = NULL );
ASSERT (CWnd *) p = this); // must be us
*/
// Note: if either of the above asserts fire and you are
// Writing a multithreaded application, it is likely that
// You have passed a C ++ object from one thread to another
// And have used that object in a way that was not intended.
// (Only simple inline wrapper functions shoshould be used)
//
// In general, CWnd objects shoshould be passed by HWND from
// One thread to another. The processing thread can wrap
// The HWND with a CWnd object by using CWnd: FromHandle.
//
// It is dangerous to pass C ++ objects from one thread
// Another, unless the objects are designed to be used in
// Such a manner.
}
}

Here I just copied it from CWnd: AssertValid, and commented out the code for MFC ing between the MFC object and the Windows object in the detection thread.

Note some comments of MFC.
// It is dangerous to pass C ++ objects from one thread
// Another, unless the objects are designed to be used in
// Such a manner.

Now, please call it in your work thread
(CTmthDlg *) pParam)-> UpdateData (FALSE );
Then debug and run. Everything works normally.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.