CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    May 1999
    Posts
    8

    Terminating a worker thread

    In a dialog-based application I have a main routine that
    creates a new thread to run a lengthy calculation process. By
    trapping certain keystokes, I want to enabled a means for the
    user to stop the calculation after it has started.

    It has been suggested to me to add a WaitForSingleObject()
    call to my CalculationProcess() routine. If I do that, what
    handle do I give it? How do I signal the process to terminate?

    I have annotated the following code snippets with
    "<<<<<<Need help here" where I have questions.

    Thanks for any help!!

    Eric

    ================================================================

    void CVCDevDlg::OnOK()
    {
    // <<snipped code>>

    if(!calcProc) //calcProc is a member variable
    calcProc = AfxBeginThread(CalculationProcess, this);

    // <<snipped code>>
    }

    BOOL CVCDevDlg::PreTranslateMessage(MSG* pMsg)
    {
    if(pMsg->message == WM_KEYDOWN)
    {
    if(IsCancelMsg(pMsg))
    {
    if(AfxMessageBox("Terminate analysis ??",
    MB_ICONQUESTION|MB_YESNO) == IDYES)
    {
    //kill calcProc thread -- how?? <<<<<<Need help here

    AfxMessageBox("Analysis terminated !!",
    MB_ICONEXCLAMATION);
    return 0;
    }
    }
    }
    return CDialog::PreTranslateMessage(pMsg);
    }

    BOOL CVCDevDlg::IsCancelMsg(MSG* pMsg)
    {
    //If calcProc is not running, then pMsg is not a CANCEL message
    if(calcProc == NULL)
    return FALSE;

    //Examine pMsg to determine is it is a CANCEL message
    if((pMsg->wParam == 67 && GetKeyState(VK_CONTROL) & 0x8000) ||
    pMsg->wParam == VK_ESCAPE)
    return TRUE;
    return FALSE;
    }

    UINT CalculationProcess(LPVOID pParam)
    {
    CVCDevDlg* pDlg = (CVCDevDlg*)pParam;
    CString str;

    if (pDlg == NULL)
    return -1; // illegal parameter

    for(long i=0; i<3000000; i++)
    {
    //My real code runs a database analysis, but
    //for this example, let's just count to 3M

    str.Format("%d", i);
    pDlg->SetDlgItemText(IDC_STATIC_STATUS, str);

    //<<<<<<Need help here
    // What handle do I give
    // to wait call?
    // Am I checking for the
    // correct return value?
    if(WaitForSingleObject(hObj, 0) == WAIT_OBJECT_0)
    {
    AfxEndThread(-1);
    }
    }

    pDlg->calcProc = NULL;
    return 0; // thread completed successfully
    }





    Eric

  2. #2
    Join Date
    May 1999
    Posts
    67

    Re: Terminating a worker thread

    WaitForObject is not a good solution, because the thread must wait for something. But you want the thread doing its work and check whether to terminate. You can do the following:

    Implement a BOOL variable (bStop) which can be accessed by both threads. Befor you start the workerthread set the bStop to FALSE. To make it threadsafe, use InterlockExchange() to set the variable. In your thread code check for bStop == TRUE to terminate. If you want the running thread to terminate, set bStop to TRUE using InterlockExchange. If you will make it very good, implement your workerthread in a class. Give the class some methods to stop. These methods can handle a class protected member variable m_bStop.....

    Hope this helps
    R.Seibert


  3. #3
    Join Date
    May 1999
    Location
    WA
    Posts
    65

    Re: Terminating a worker thread

    I ran into this problem on one of my projects recently, and the way I solved it may not have been the best possible solution, but it worked, and it was easy to understand. Here it is:

    In my main dialog class I had a BOOL member called m_bEndThread and when I started my worker thread (in the passed in structure to your worker thread) I passed in a pointer to my dialog class. In the main dialog class (that starts the worker thread) I have a public accessor function called "BOOL ShouldWorkerThreadExitPrematurely()" and all it does is return m_bEndThread. Then in the loop in your worker thread, use your pointer to the main dialog class to call that function, for example:

    UINT MyWorkerThread( LPVOID pVoid )
    {
    for( int x = 1; x < 10000; x++ )
    {
    if( pMyDialog->ShouldWorkerThreadExitPrematurely() )
    {
    AfxEndThread(1);
    }
    }


    NOTE: When you call your worker thread, set the m_bEndThread to FALSE. Then if you encounter a TRUE variable when calling the ShouldThreadExitPrematurely() function, you know to call your AfxEndThread(1); to exit the thread prematurely. If the thread exits normally, then you're all set.

    Hope that this helps you. It's not the best solution, but it will give you something to think about, and it's easy to understand. Good luck.



    - Troy

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured