From: Goran on 24 Oct 2009 02:21 Whoops, how wrong was I... I __presumed__, apparently wrongly, that your thread is a worker thread without a message loop (but with a thread function). If you have a message loop, I will be presuming that you did something like this to create the thread: pMyThread = AfxBeginThread(..., CREATE_SUSPENDED/*ESSENTIAL*/, ...); if (NULL = pMyThread) AfxThrowResourceException(); // Or something else // Note that AfxBeginThread might throw, too! pMyThread->m_bAutoDelete = FALSE; // ESSENTIAL VERIFY(pMyThread->ResumeThread() == 1); .... and that you are holding onto pMyThread correctly. If your thread works through a message loop, then forget about a shared termination flag. Use pMyThread->PostThreadMessage (WM_SOMETHING). AFAIK, WM_SOMETHING can be WM_QUIT, but note that WM_QUIT is a bit special (http://blogs.msdn.com/oldnewthing/archive/ 2005/11/04/489028.aspx). In a thread with a message loop, you should _not_ use a shared "termination" flag. You should NOT use an exception to break out. Even with a message loop, you should still NOT use AfxTerminateThread. From the main thread, when you decide to stop pMyThread, you do: VERIFY(pMyThread->PostThreadMessage(WM_SOMETHING, ...)); VERIFY(WaitForSingleObject(*pMyThread, INFINITE) == WAIT_OBJECT_0); delete pMyThread; // "Official" MFC way is pMyThread->Delete(). That is STUPID and I won't do it. YOU have to make sure, through organization of your code^^^, that the thread will pick the message up quickly enough so that you don't block in WFSO for a long time, thereby having e.g. poor user experience (there's NO magic trick, YOU have to do it). ^^^ "worker" threads with message loops are only good if all they do are short bursts of activity caused by messages posted to them. Goran.
From: Joseph M. Newcomer on 24 Oct 2009 21:23 See below.... On Fri, 23 Oct 2009 03:16:10 -0700 (PDT), Frank <jerk(a)gmx.de> wrote: >Dear people, > >I create a subthread of my main program by calling > > >AfxBeginThread(RUNTIME_CLASS(CMySubThread)); > > >CMySubThread is derived from CWinThread. Eventually, >I'd like to terminate the thread. So I clean all variables, >buffer memory and the like, then call AfxEndThread(0) >from within a member function of CMySubThread. **** Forget that you ever heard of this function. Do not ever call ExitThread as an API or any of its thinly-disguised equivalences (such as AfxEndThread). Don't do it. Ever. To terminate the thread, you return from the top-level thread function. That is the ONLY correct way to terminate a thread. Any other technique opens you to all kinds of potentially serious problems. **** > >The problem: This call seems to close the whole application, >it throws an exception in: > >(code from AfxEndThread): > >AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState(); >CWinThread* pThread = pState->m_pCurrentWinThread; >if (pThread != NULL) > { > ASSERT_VALID(pThread); > ASSERT(pThread != AfxGetApp()); > > >The last ASSERT causes the problem. > >Now there are two questions: >- Why does the call try to close the whole app > instead of the thread? *** Could it be because you are calling AfxEndThread from the main thread? You have give NO context for where you call it. A classic blunder is class CMyThread : public CWinThread { public: Stop() { AfxEndThread(0); } }; class CMyView : public CView { protected: CMyThread * thread; Stop() { thread->Stop(); } }; which of course will stop your app, because while AfxExitThread will exit a thread, *it is called in the context of your main GUI thread*, and therefore stops your app! This is because it has meaning ONLY when called from the thread context itself. The above example does not do that. But don't ever use AfxExitThread. Exit from your top-level thread function. Since you have shown no code at all, there is absolutely no way telll what you have done or how to fix it. **** >- And how can I safely terminate the thread? **** If it is a UI thrread, PostQuitMessage(0) from within the thread itself. joe **** > > >TIA! Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on 24 Oct 2009 21:28 See below... On Fri, 23 Oct 2009 07:28:32 -0700 (PDT), Frank <jerk(a)gmx.de> wrote: >Scott McPhillips wrote: > >> The thread must terminate itself. Just because you call from within a >> member function of the thread class does not mean you are calling from the >> thread. I.e., calling a function from the main thread means the function >> executes in the main thread, no matter what class the function is part of. >> >> The thread must call PostQuitMessage(0) to exit. Your main thread can >> request the secondary thread to exit by posting a custom message to it or by >> signaling an event that the thread monitors. > >I tried that: Had the main thread post a message >to the thread (PostThreadMessage), in the message handler > >- call AfxEndThread **** Forget you ever heard of AfxEndThread. Never, ever, under any imaginable circumstances should you call it. It does not exist. It is a figment of someone's imagination. Do not, ever, ever, ever call it yourself. Note that since you call AfxEndThread, none of the code below will ever be executed! So it is pointless code. I'm curious: why does stoppping the thread close the main app. And why would you ever, EVER want to PostMessage a WM_QUIT to the main GUI thread (answer: because you have no idea what you are doing!) This function will close the main GUI thread as well. But worse still, it will stop the message pump even when there are still important messages to be processed! The WM_CLOSE will close the main thread. STOP RIGHT THERE! DO NOT POST A WM_QUIT TO THE MAIN MESSAGE LOOP, EVER! joe **** >- PostQuitMessage(0) >- m_pMainWnd->PostMessage(WM_CLOSE, 0, 0) >- m_pMainWnd->PostMesage(WM_QUIT, 0, 0) > >Everything closes the main program. **** Are you surprised? You asked it to do so. **** > >Do I have to do something about the message queue >of the subthread or something? **** No. Once you PostQuitMessage to it, you are done. joe **** Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Frank on 26 Oct 2009 04:05 Joseph M. Newcomer wrote: > On Fri, 23 Oct 2009 07:28:32 -0700 (PDT), Frank <j...(a)gmx.de> wrote: > >I tried that: Had the main thread post a message > >to the thread (PostThreadMessage), in the message handler > > >- call AfxEndThread > > **** > Forget you ever heard of AfxEndThread. Never, ever, under any imaginable circumstances > should you call it. It does not exist. It is a figment of someone's imagination. Do > not, ever, ever, ever call it yourself. > > Note that since you call AfxEndThread, none of the code below will ever be executed! So > it is pointless code. Sorry Joseph, it seems to me that you believe I put all those statements into the code. My bad. I tried all these statements but only one at a time.
From: Joseph M. Newcomer on 26 Oct 2009 08:24 On Mon, 26 Oct 2009 01:05:04 -0700 (PDT), Frank <jerk(a)gmx.de> wrote: >Joseph M. Newcomer wrote: > >> On Fri, 23 Oct 2009 07:28:32 -0700 (PDT), Frank <j...(a)gmx.de> wrote: > >> >I tried that: Had the main thread post a message >> >to the thread (PostThreadMessage), in the message handler >> >> >- call AfxEndThread >> >> **** >> Forget you ever heard of AfxEndThread. �Never, ever, under any imaginable circumstances >> should you call it. �It does not exist. �It is a figment of someone's imagination. �Do >> not, ever, ever, ever call it yourself. >> >> Note that since you call AfxEndThread, none of the code below will ever be executed! �So >> it is pointless code. > >Sorry Joseph, it seems to me that you believe I put all >those statements into the code. My bad. I tried all these >statements but only one at a time. **** That was not clear. So let's look at them, one at a time: - call AfxEndThread Always, without exception, the wrong thing to do - PostQuitMessage(0) Yes, this is how you stop your UI thread, but you must be sure that no other message can be posted after this one! - m_pMainWnd->PostMessage(WM_CLOSE, 0, 0) This tells your app to quit cleanly, except that is apparently not what you wanted to do - m_pMainWnd->PostMesage(WM_QUIT, 0, 0) This kills your app, badly, and is always a mistake joe **** Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
First
|
Prev
|
Pages: 1 2 Prev: Multiple closed networks and UDP. Please help me. Next: 17 KewaSa.com DDL Torrents |