Re: Ask a surprising question
Lee Tow wrote:
Hello all:
Look:
CDgl *p; //CDgl is a class of Dialog
UINT Thread1( LPVOID pParam )
{
int *pi=(int*)pParam;
CString str;
str.Format("%d",*pi);
CWnd* pE=p->GetDlgItem(IDC_EDIT1);
pE->SetWindowText(str);
return 0;
}
UINT Thread2( LPVOID pParam )
{
int *pi=(int*)pParam;
CString str;
str.Format("%d",*pi);
CWnd* pE=p->GetDlgItem(IDC_EDIT2);
pE->SetWindowText(str);
return 0;
}
void CDgl::OnButton1()
{
// TODO: Add your control notification handler code here
HWND hWnd=GetSafeHwnd();
p=(CDlg*)CWnd::FromHandle(hWnd);
int a1=123,a2=456;
LPVOID tt1,tt2;
tt1==(void*)&a1;
tt2==(void*)&a2;
AfxBeginThread(Thread1,tt1);
AfxBeginThread(Thread2,tt2);
//Sleep(10);
}
when I don't add the last line:Sleep(10),the running result is that
the thread1 is right,but the thread2 is error;but when I add the last
line:Sleep(10),the running result are all right,I want to know why?
Thank you very much.
Lee Tow:
I'm not sure why the Sleep() makes it (seem to) work, but when a Sleep()
is required to make a multi-threaded program work, it is a sure sign
that the program is really in error.
Here you are doing two things you should never do:
(a) Using MFC objects across a thread boundary
(b) Manipulating a window from a thread different from the one that
created it.
The only correct method to do this kind of thing is to create a custom
message in your dialog class, and use SendMessage() or PostMessage()
from the thread. In the handler, update the controls as needed.
Basically, all GUI calls of any kind should be in the main thread.
BTW, it is possible to call cross-thread CWnd::SendMessage() or
CWnd::PostMessage() on an MFC pointer, but purists would have you use
the m_hWnd member and use ::SendMessage() or ::POstMessage().
David Wilkinson