Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Safer Timer Thread termination

Safer Timer Thread termination

Scheduled Pinned Locked Moved C / C++ / MFC
debugginghelp
3 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    I was experimenting on a worker thread to do a timer which posts a message each second and the thread is created in the CView constructor (MY APP is SDI) class CMyView:public CView { //consturctor ... public: static UINT RunTimer(LPVOID p); void Run(); public: volatile BOOL m_bRunTimer; //other stuff }; CMyView::CMyView() { m_bRunTimer=TRUE; //Initialize Stuff AfxBeginThread(RunTimer,this); //Get A Thread To Post A Message Every Second } the Run Timer Function is used in This Way ///////////////////////////////////////////////// UINT CMyView::RunTimer(LPVOID p) { ((CMyView*)p)->Run (); return 0; } void CMyView::Run () { while (m_bRunTimer) { ::Sleep (1000); PostMessage (UWM_TIMER_SECOND); /*Note Here that UWM_TIMER_MESSAGE IS user Defined Message*/ } } every thing works great till this point and the thread posts a message each second and the message handling is doin great the problem arises when the window(program) is closed then a debug assertion failure dialog box is displayed saying the when we are Posting a message we are posting a message to a window that no longer exists. I tried adding The line m_bRunTimer=FALSE; in ~CMyView() but no change then i wrote some code in the void CMyView::OnDestroy() { m_bRunTimer=FALSE; ::Sleep(4000);//Simply Added to Elapse the Time Slice of Main Thread CView::OnDestroy(); } After Doing i finally got safe with removing the thread and returns value i used TRACE() that my thread is safley removed and everything but i think my way of getting rid of the thread is kind of not portable and clean is there any other way that i can do this safley.

    D B 2 Replies Last reply
    0
    • L Lost User

      I was experimenting on a worker thread to do a timer which posts a message each second and the thread is created in the CView constructor (MY APP is SDI) class CMyView:public CView { //consturctor ... public: static UINT RunTimer(LPVOID p); void Run(); public: volatile BOOL m_bRunTimer; //other stuff }; CMyView::CMyView() { m_bRunTimer=TRUE; //Initialize Stuff AfxBeginThread(RunTimer,this); //Get A Thread To Post A Message Every Second } the Run Timer Function is used in This Way ///////////////////////////////////////////////// UINT CMyView::RunTimer(LPVOID p) { ((CMyView*)p)->Run (); return 0; } void CMyView::Run () { while (m_bRunTimer) { ::Sleep (1000); PostMessage (UWM_TIMER_SECOND); /*Note Here that UWM_TIMER_MESSAGE IS user Defined Message*/ } } every thing works great till this point and the thread posts a message each second and the message handling is doin great the problem arises when the window(program) is closed then a debug assertion failure dialog box is displayed saying the when we are Posting a message we are posting a message to a window that no longer exists. I tried adding The line m_bRunTimer=FALSE; in ~CMyView() but no change then i wrote some code in the void CMyView::OnDestroy() { m_bRunTimer=FALSE; ::Sleep(4000);//Simply Added to Elapse the Time Slice of Main Thread CView::OnDestroy(); } After Doing i finally got safe with removing the thread and returns value i used TRACE() that my thread is safley removed and everything but i think my way of getting rid of the thread is kind of not portable and clean is there any other way that i can do this safley.

      D Offline
      D Offline
      Doug Mitchell
      wrote on last edited by
      #2

      IMO, after signalling the thread to stop you should use WaitForSingleObject.

      1 Reply Last reply
      0
      • L Lost User

        I was experimenting on a worker thread to do a timer which posts a message each second and the thread is created in the CView constructor (MY APP is SDI) class CMyView:public CView { //consturctor ... public: static UINT RunTimer(LPVOID p); void Run(); public: volatile BOOL m_bRunTimer; //other stuff }; CMyView::CMyView() { m_bRunTimer=TRUE; //Initialize Stuff AfxBeginThread(RunTimer,this); //Get A Thread To Post A Message Every Second } the Run Timer Function is used in This Way ///////////////////////////////////////////////// UINT CMyView::RunTimer(LPVOID p) { ((CMyView*)p)->Run (); return 0; } void CMyView::Run () { while (m_bRunTimer) { ::Sleep (1000); PostMessage (UWM_TIMER_SECOND); /*Note Here that UWM_TIMER_MESSAGE IS user Defined Message*/ } } every thing works great till this point and the thread posts a message each second and the message handling is doin great the problem arises when the window(program) is closed then a debug assertion failure dialog box is displayed saying the when we are Posting a message we are posting a message to a window that no longer exists. I tried adding The line m_bRunTimer=FALSE; in ~CMyView() but no change then i wrote some code in the void CMyView::OnDestroy() { m_bRunTimer=FALSE; ::Sleep(4000);//Simply Added to Elapse the Time Slice of Main Thread CView::OnDestroy(); } After Doing i finally got safe with removing the thread and returns value i used TRACE() that my thread is safley removed and everything but i think my way of getting rid of the thread is kind of not portable and clean is there any other way that i can do this safley.

        B Offline
        B Offline
        Blake Miller
        wrote on last edited by
        #3

        I was thinking that the problem could be solved with another safety check. Make sure the window exists before posting the message! if( ::IsWindow(m_hWnd) ){ PostMessage (UWM_TIMER_SECOND); } Note that you want to invoke the GLOBAL IsWindow and not the class-specific override, that is whyt he :: is in front of the function name. Now, you avoid your crash, and some other issue you might not have discovered yet. I always make sure the target window still exists before posting or sending a mesage from a different thread. Now, if you waited on an event and sets its timeout to 1000 milliseconds, you could signal the event from your main thread, and the timer thread could exit sooner (instead of always being asleep for 1 second). If you see WAIT_OBJECT_0 you exit the thread, otherwise, if it gets WAIT_TIMEOUT, you just post your message as normal. This way, your main app would not necessarily need to wait 4 seconds, it could exit immediately. Also, a s the other person suggests, you can wait on the timer thread handle in the main thread to know when the timer thread was done.

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups