Click to See Complete Forum and Search --> : Terminating Worker Thread from my UI thread causing problem?
dp_76
October 6th, 2007, 02:36 AM
Hi
From the main thread of my NFC based SDi application, i am creating a UI thread. Now from within the UI thread, i am creating a worker thread that does a very crucial job.
This worker thread has the tendancy to hang in certain situations.
To handle this hang sitaution, i wait on this worker thread from my UI thread for a max of 60 seconds using WaitForSingleObject(pThread->m_hTread, 60000).
Please have a look at the code snippet:
//This is a function in my UI thread.
BOOL CDocRecover::QuickRepair()
{
---
--- //some code goes here.
---
//Now here i am creating a worker thread.
CWinThread* pThread = AfxBeginThread(Worker_ThreadSample, wordDocs);
DWORD dwReturnValue = WaitForSingleObject(pThread->m_hThread, 60000);
if(dwReturnValue ==WAIT_TIMEOUT)
{
DWORD lpExitCode = 0;
GetExitCodeThread(pThread->m_hThread, &lpExitCode);
while(TerminateInstance(TRUE)==TRUE);
if(wordApp1.m_lpDispatch)
{
wordApp1.ReleaseDispatch();
wordApp1.Quit(covFalse, covTrue, covFalse);
DeleteFile(pApp->strTargetPath);
}
if(lpExitCode==STILL_ACTIVE)
AfxEndThread((UINT)lpExitCode);
}
int dp=0;
}
Now assuming that the worker thread has hanged, after waiting for 60 seconds the control will come inside the if(dwReturnValue ==WAIT_TIMEOUT) block & worker thread will be terminated after releasing some dispatch.
Now the problem is that after the call to AfxEndThread(), the control never reaches the line int dp=0;
I DONOT KNOW WHY?
The Application has not hanged but the control never returns to the UI thread.
Please suggest
Regards :(
kirants
October 6th, 2007, 10:01 AM
Please read up note on AfxEndThread and all will be clear why you see the behavior.
http://msdn2.microsoft.com/en-us/library/2s21xzfe(VS.71).aspx
Having said that, have you investigated as to why the worker thread hangs ? That itself is not a good sign and you might be better off fixing it. Do you have any means of letting the worker thread know it has to stop doing what it is doing and shut itself down ?
JVene
October 6th, 2007, 05:29 PM
I second that opinion!
You may be thinking of TerminateThread, but the documentation says it's "a dangerous function", and they're right.
I've developed threaded applications for over a decade, and I can say with 99.999% certainty that termination of a thread by any non-graceful means is a dangerous practice. There is usually (as in hardly ever otherwise) a better way to handle the reason you're tempted to just kill the thread.
Can you take us into the hanging notion? That's really where you need the assistance.
Arjay
October 6th, 2007, 05:44 PM
Part of the problem is that you are using WaitForSingleObject in the main UI thread. I'm guessing that you have initialized the UI thread as an apartment model in order to use the wordApp1 Word Automation interface. If so, the apartment model requires that you continue to process messages (as COM uses the messaging subsystem to transfer COM messages).
Since you are sleeping on the main thread, I believe this is causing everything to get bound up.
Instead of using WaitForSingleObject, use MsgWaitForMultipleObjects and pump messages while waiting. Search this forum for the MsgWaitxxx function for sample code on how to pump.
dp_76
October 8th, 2007, 03:33 AM
Having said that, have you investigated as to why the worker thread hangs ? That itself is not a good sign and you might be better off fixing it. Do you have any means of letting the worker thread know it has to stop doing what it is doing and shut itself down ?
Yes i have investigated as to y the worker thread hangs.
Actually in the worker thread i am using WORD Automation functions & try to open the word file.The thread actually hangs in the AttachDispatch() function in case the WORD file is heavily corrupted.
So if the word file is corrupted i cannot do anything about it & thread hangs.That is why i wait for 60 seconds(good enough time open a good word file).
Please suggest.
Since you are sleeping on the main thread, I believe this is causing everything to get bound up.
I am not sleeping my main application thread.
Thread hierarchy is like this:
Main Application Thread -----> UI THread -----> Worker Thread.
I am waiting in the UI Thread using WaitForSingleObject().
Please Suggest
Regards :thumb:
Arjay
October 8th, 2007, 03:44 AM
I am not sleeping my main application thread.
I am waiting in the UI Thread using WaitForSingleObject().
Using WaitForSingleObject() in any thread puts the thread to sleep during the wait.
dp_76
October 9th, 2007, 12:48 AM
Hi
After the wait period has expired, the worker thread is terminated & the control must move forward in the UI thread(from where the worker thread is invoked).
But this not happening & the UI thread is not able to finish.
Also note that my application at this point is not hanged. I can play with the tollbar/menu etc & can do other things.
Please have a look at the worker thread code.
UINT Worker_ThreadSample(LPVOID pParam)
{
CMyRecApp* pApp = (CMyRecApp*)AfxGetApp();
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
bOpenWorkerThreadResult = FALSE;
COleVariant covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
TRY
{
if(wordApp1.CreateDispatch(_T("Word.Application")))
{
wordDocs1 = wordApp1.GetDocuments();
wordDoc1.AttachDispatch(wordDocs1.Open(COleVariant(pApp->strTargetPath),
covFalse,covFalse,covFalse,
COleVariant(_T("")),COleVariant(_T("")),covFalse,
COleVariant(_T("")),COleVariant(_T("")),covOptional,
covFalse,covFalse));
wordDoc1.Select();
wordSelect1 = wordApp1.GetSelection();
if(pApp->ViewOnly)
{
int iType = wordDoc1.GetProtectionType();
if(iType != 2)
wordDoc1.Protect(2, covFalse, COleVariant(_T("abcd")));
}
wordDoc1.SaveAs(COleVariant(pApp->strTargetPath),COleVariant((long)0),
covFalse,COleVariant(_T("")),covTrue,
COleVariant(_T("")),covFalse,covFalse,covFalse,
covFalse, covFalse);
bOpenWorkerThread = 1;
}//eof if(app.CreateDispatch(_T("Word.Application")))
else
{
bOpenWorkerThread = FALSE;
bOpenWorkerThreadResult = FALSE;
}
if(bOpenWorkerThread)
{
if(wordApp1.m_lpDispatch)
{
wordApp1.ReleaseDispatch();
wordApp1.Quit(covFalse, covTrue, covFalse);
bOpenWorkerThreadResult = TRUE;
}
}//eof if(oApp.m_lpDispatch)
}
CATCH_ALL(e)
{
if(wordApp1.m_lpDispatch)
{
wordApp1.ReleaseDispatch();
wordApp1.Quit(covFalse, covTrue, covFalse);
//while(TerminateInstance(TRUE)==TRUE);
DeleteFile(pApp->strTargetPath);
bOpenWorkerThreadResult = TRUE;
bOpenWorkerThread = FALSE;
}//eof if(oApp.m_lpDispatch)
}
END_CATCH_ALL
return 0;
}
Waiting for suggestions
Regards
Arjay
October 9th, 2007, 10:50 AM
A couple of questions.
Where are the wordDoc1 and wordDocs1 variables declared (I don't see them declared in the threadproc)? Are these variables shared between threads?
I noticed the strTargetPath is shared between threads. Is this value always read only during the threading operations? If not, you'll need to protect it with a synchronization object (cs, mutex, etc.).
dp_76
October 10th, 2007, 03:15 AM
Where are the wordDoc1 and wordDocs1 variables declared
These are global variables.
I noticed the strTargetPath is shared between threads. Is this value always read only during the threading operations?
Yes strTargetPath is read only during the threading operation so no need for synchronization.
I still cannot make out y the UI thread is not completing.
Waiting for the suggestions
Regards
Arjay
October 10th, 2007, 11:40 AM
Sharing the global variables between threads is going to cause problems - maybe even the problems you are seeing.
kirants
October 10th, 2007, 11:40 PM
Are you saying that , if the word document is not corrupted all is well ?
Also, if a document that is passed is corrupt, are you seeing that the wordDocs1.Open call itself is blocked forever ? Are you really seeing that ?
To make matters simpler, have you tried just executing that thread code only in a sample application that does nothing else ? Just to rule out other cross communication dependencies.
UnderDog
October 16th, 2007, 02:36 AM
Would "int i = 0" line execute if you write the following in any of your thread?
ExitThread(0);
int i = 0;
AfxEndThread((UINT)lpExitCode);
kills your currently executing thread; the UI thread.
If you want to kill some other thread, NOT the 'current' thread, look up TerminateThread in MSDN.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.