Background:
In my C ++ application, I create a work thread, which in turn creates two threads using CreateThread()
. The two threads that the workflow creates communicate with the WCF service through a client, which is implemented using the Windows Web Services API , which offers C / C ++ programming interface (API) for creating SOAP-based web services and clients. My application only implements a client using this API.
Problem:
The problem I am facing is that all other threads are exiting gracefully, with the exception of the worker thread, as you can see in the image below, that WorkerThreadProc
does not use CPU cycles, but does not exit. There are also several other threads that are not created by me, but at runtime.
The state of the stream is as follows (as ProcessExplorer reports):
WorkerThreadProc
is in a Wait state : WrUserRequest .wWinMainCRTStartup
is in a Wait state : UserRequest .- All
TpCallbackIndependent
are in a Wait state : WrQueue .
What are they waiting for? What are the possible reasons why I need to look? Also, what is the difference between WrUserRequest and UserRequest? And what does WrQueue mean? I absolutely do not know what is going on here.

Here is my WorkerThreadProc code. I deleted all registration instructions, except the last one, at the bottom of the function:
DWORD WINAPI WorkerThreadProc(PVOID pVoid) { //Initialize GDI+ GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; Status status = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); if ( status != Status::Ok ) { return 1; } GuiThreadData *pGuiData = (GuiThreadData*)pVoid; auto patternIdRequestQueue= new PatternIdRequestQueue(); auto resultQueue = new ResultQueue(); auto patternManager = new PatternManager(patternIdRequestQueue); LocalScheduler *pScheduler = new LocalScheduler(resultQueue, patternManager); bool bInitializationDone = pScheduler->Initialize(pGuiData->m_lpCmdLine); if ( !bInitializationDone ) { return 0; } //PatternIdThread PatternIdThread patternIdThread(patternIdRequestQueue); DWORD dwPatternIdThreadId; HANDLE hPatternIdThread = CreateThread(NULL, 0, PatternIdThreadProc, &patternIdThread, 0, &dwPatternIdThreadId); ResultPersistence resultPersistence(resultQueue); DWORD dwResultPersistenceThreadId; HANDLE hResultPersistenceThread = CreateThread(NULL, 0, ResultPersistenceThreadProc, &resultPersistence, 0, &dwResultPersistenceThreadId); pScheduler->ScheduleWork(pGuiData->m_hWnd, pGuiData->m_hInstance, ss.str()); pScheduler->WaitTillDone(); patternIdThread.Close(); resultPersistence.Close(); delete pScheduler; //Uninitialize GDI+ GdiplusShutdown(gdiplusToken); dwRet = WaitForSingleObject(hPatternIdThread, INFINITE); CloseHandle(hPatternIdThread); dwRet = WaitForSingleObject(hResultPersistenceThread,INFINITE); CloseHandle(hResultPersistenceThread); SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0); //IMPORTANT : this verbose message is getting logged! T_VERBOSE(EvtSrcInsightAnalysis, 0, 0, "After sending message to destroy window"); delete patternManager; delete patternIdRequestQueue; delete resultQueue; return 0; }
See macro T_VERBOSE
, it is used to register a detailed message. I see that the message is being logged, but the stream does not exit!
EDIT:
I just commented on the next line in WorkerThreadProc
, then the workflow exits gracefully!
SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0);
Does this mean that SendMessage
is the culprit? Why does it block the thread by the calling thread?