[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1489
  • Last Modified:

WaitForSingleObject blocks while waiting for the CWinThread

Hi, i have a dialog based MFC application and i am using CListCtrl to populate the list. As the number of items in the list are too high, i am using a CWinThread to handle this. Below is the summary of actions that are being performed

1) From OnInitDialog i create a CWinThread(say m_listCtrlThread) and i resume it soon after that. I am using a flag called  
2) The thread starts running and I see my CListCtrl being populated.
3) While it is being populated I want to exit from my dialog by clicking the Ok button. But my main application blocks while waiting for the subordinate thread. I have used both WaitForSingleObject,MsgWaitForMultipleObjects. Can someone tell me where I am going wrong. Below is the sample code.....

MyDialog::OnInitDialog()
{
   isokToExit = false; //this is a member flag which will be used later
   //create CWinThread(m_listCtrlThread) and resume it soon after it in MyThreadProc
  return TRUE;
}

MyThreadProc(LPARAM b)
{
   MyDialog *dlg = (MyDDialog *)b;
  dlg->ShowListCtrl();
}

ShowListCtrl()
{
 while(some condition)
{
  if(!isokToExit) //This flag will be set when we press the OnOK button
   {
     //keep on showing the list 20 records at a time and after every 20 records sleep(200);
   }
  else
   break;
 }
 
}

 OnOK()
{
  if(!isokToExit)
 {
   isokToExit = true; //Set the flag to true so that we break from the ShowListCtrl loop immediately
   WaitForSingleObject(m_listCtrlThread->m_hThread,INFINITE); //This call blocks here and never returns, i donot want to return by putting some timeout period
   //MsgWaitForMultipleObjects(1,&(m_listCtrlThread->m_hThread),FALSE,INFINITE,QS_ALLEVENTS); //This doesnot return either
  }
  CloseHandle(m_listCtrlThread->m_hThread);
  CDialog:OnOK();
}
0
ncheeku14
Asked:
ncheeku14
  • 3
  • 3
  • 2
  • +1
2 Solutions
 
jkrCommented:
Are you calling 'ExitThread()' properly when your CWinThread terminates?
0
 
ncheeku14Author Commented:
From where shall i call ExitThread, i assume that when i go out of the  ShowListCtrl, it cleans it up automatically
0
 
jkrCommented:
Well, it actually should ;o)

But, to rule out other things, are you sure that the thread exits? You could try a

MyThreadProc(LPARAM b)
{
   MyDialog *dlg = (MyDDialog *)b;
  dlg->ShowListCtrl();
  OutputDebugString("Thread terminating");

  ExitThread(0);
}

(These 'OutputDebugString()' messages can be seein either in the debugger or with http://www.sysinternals.com/Utilities/DebugView.html)
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
AlexFMCommented:
Please show more code: strarting thread and thread function. All details are important.
0
 
ncheeku14Author Commented:
I tried the followong:
      dwRet = MsgWaitForMultipleObjects(1, &(m_ListCtrlThread->m_hThread), FALSE, INFINITE, QS_ALLINPUT );  
This call returns with a value of 1, however I want to return only when my thread has exited
heres my code below with more details.

BOOL MyDlg::OnInitDialog()
{
      CDialog::OnInitDialog();
               //...other list specific inititialization
      isokToExit = true;
      m_ListCtrlThread = AfxBeginThread((AFX_THREADPROC)UpdateListCtrl,
            (LPVOID)this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL);
      
      ResumeListCtrlThread();
      
      return TRUE;  // return TRUE unless you set the focus to a control
                    // EXCEPTION: OCX Property Pages should return FALSE
}


UINT MyDlg::UpdateListCtrl( LPVOID pParam )
{      
      MyDlg * dl = (DlgCallHist *)pParam;
      
      dl->ShowList();

      DBG2(L"Display Entries Called: %#x", dl);
      

      return 0;
}

void MyDlg::ResumeListCtrlThread()
{      
      isokToExit = false;
      m_ListCtrlThread->ResumeThread();
      
}

void MyDlg::PeekMessageLoop()
{
      MSG msg;
      trc(L"Inside PeekMessageLoop");
    while (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}



void DlgCallHist::OnOK()
{
      if(!isokToExit)
      {      
            isokToExit = true;

            DWORD dwRet;
            
                  dwRet = MsgWaitForMultipleObjects(1, &(m_ListCtrlThread->m_hThread), FALSE, INFINITE, QS_ALLINPUT );  //I want to retun here only when my thread has exited
                  if (dwRet == WAIT_OBJECT_0 + 1)
                   {
                         PeekMessageLoop();
                  }
            

      }
      if(m_ListCtrlThread->m_hThread != NULL)
      {
            CloseHandle(m_ListCtrlThread->m_hThread);
            m_ListCtrlThread->m_hThread = 0;
      }
      CDialog::OnOK();
      
}


void MyDlg::ShowList()
{

      // initialization
      int counter = 0;
      do{      
       if(!isokToExit)
       {
            if(counter == 20)
            {
                  trc(L"Counter of 20");
                  counter = 0;
                  Sleep(100);
            }
            counter++;
       }
       else
                {            
                    break;
       }
            
      }while(somecondition);
            isokToExit = true;
      
      

}

0
 
AlexFMCommented:
Is this full ShowList function? Important thing is: does this function send messages to the dialog? It is not clear from function text, which looks like strange set of loops, couters and sleep calls.
What is result of trc calls?
0
 
mrblueCommented:
Can you debug it ?
Do you reach  
isokToExit = true;           // set breakpoint here
in ShowList()
0
 
ncheeku14Author Commented:
Actually i added this do while loop and it seems to work.
 do
{
dwRet = MsgWaitForMultipleObjects(1, &(m_ListCtrlThread->m_hThread), FALSE,
                               INFINITE,
                               QS_ALLINPUT
                               );
      if (dwRet == WAIT_OBJECT_0 + 1)
       {
             PeekMessageLoop();
      }
            
} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));


i want to split the points for jkr and AlexFM, how can i do that?? where is the option to split the points?
0
 
AlexFMCommented:
There is Split button in the bottom part of the page.
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

  • 3
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now