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. Threads in Windows service

Threads in Windows service

Scheduled Pinned Locked Moved C / C++ / MFC
questioncsharp
4 Posts 2 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.
  • R Offline
    R Offline
    RoyceF
    wrote on last edited by
    #1

    I have a Windows service in which I need to stop worker threads from my main thread. I am trying to use events to do this but I am stumped on why it is not working. Each class that runs a worker thread creates a stop event and a response event. When I need to stop the worker thread I call into the threads class and set the event. However, instead of the worker thread detecting that the event has been set and stopping gracefully, it just disappears. Why? What is the best method for stopping a worker thread from the main thread? Re-posted from the C# forum.

    B 1 Reply Last reply
    0
    • R RoyceF

      I have a Windows service in which I need to stop worker threads from my main thread. I am trying to use events to do this but I am stumped on why it is not working. Each class that runs a worker thread creates a stop event and a response event. When I need to stop the worker thread I call into the threads class and set the event. However, instead of the worker thread detecting that the event has been set and stopping gracefully, it just disappears. Why? What is the best method for stopping a worker thread from the main thread? Re-posted from the C# forum.

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

      This should work quite well. I do it all the time. Something else is wrong. Of course, your thread must periodically be 'waiting'on the event. If you require a polled approach because your thread is always working and does not return to check for the 'main event' too often, then you can use InterLockedIncrement and InterlockedCompareExchange on a control variable.

      R 1 Reply Last reply
      0
      • B Blake Miller

        This should work quite well. I do it all the time. Something else is wrong. Of course, your thread must periodically be 'waiting'on the event. If you require a polled approach because your thread is always working and does not return to check for the 'main event' too often, then you can use InterLockedIncrement and InterlockedCompareExchange on a control variable.

        R Offline
        R Offline
        RoyceF
        wrote on last edited by
        #3

        I appreciate any help. I have posted my code below: void CFileChangeEvent::stopProcessThread() { TRACE( "> > > > CFileChangeEvent::stopProcessThread() entered - Event handles < %X, %X >, Event ID < %s >\n", m_hProcessStopEvent, m_hProcessRespEvent, getIdentifier() ); // The ProcessStopEvent is used by the main thread to tell the worker thread to stop. // In turn, the worker thread sets the ProcessRespEvent to tell the main thread that it has stopped. ::SetEvent( m_hProcessStopEvent ); } UINT CFileChangeEvent::MultiFileProcessThread( LPVOID lpParam ) { // This is the threaded multi-file processor. It searches for and processes all raw flight data // (*.FIF files) in the Inbox or until it is cancelled by a call from DataMovement due to // a Cancel message from PC-GBS. CFileChangeEvent* pEvent = (CFileChangeEvent*)lpParam; CFlightDataHandler* pFlightDataHandler = NULL; CLogWriter* pLogWriter = NULL; HANDLE hProcessStopEvent = pEvent->getProcessStopEvent(); HANDLE hProcessRespEvent = pEvent->getProcessRespEvent(); // We use this exception handling merely to protect this service // from being crashed by an unhandled exception. Errors are // generally handled and logged within the DLL by the LogWriter. try { CDataMovement* pDataMovement = pEvent->getDataMovementParent(); CLogWriter* pLogWriter = pDataMovement->getLogWriter(); pFlightDataHandler = new CFlightDataHandler( pLogWriter ); // We must call ::CoInitialize() each time the database is accessed HRESULT hRes = ::CoInitialize(NULL); CString strInboxPath( pDataMovement->getInboxPath() ); vector<CString> vecFifFiles = UtilK::findAllFiles( "*.fif", strInboxPath ); // The input file parameter points to a single *.fif file, but we // need to extract the folder just below the Inbox path so that // all flight data in that path can be processed int nLen = strInboxPath.GetLength() + 1; vector<CString>::iterator iterFile = vecFifFiles.begin(); CString strFile = *iterFile; CString strLastPath = (*iterFile).Mid( 0, strFile.Find( "\\", nLen ) ); int nFileCount = 0; bool bCancelled = false; for( ; iterFile != vecFifFiles.end() && ! bCancelled; iterFile++ ) { CString strPath = UtilK::getFsPart( *iterFile, UtilK::FsPath ); pFlightDataHandler->importRawFlightData( strPath ); DWORD dwWaitStatus = ::WaitForSingleObject( hProcessStopEvent, 1 ); if ( dwWaitStatus == WAIT_FAILED

        B 1 Reply Last reply
        0
        • R RoyceF

          I appreciate any help. I have posted my code below: void CFileChangeEvent::stopProcessThread() { TRACE( "> > > > CFileChangeEvent::stopProcessThread() entered - Event handles < %X, %X >, Event ID < %s >\n", m_hProcessStopEvent, m_hProcessRespEvent, getIdentifier() ); // The ProcessStopEvent is used by the main thread to tell the worker thread to stop. // In turn, the worker thread sets the ProcessRespEvent to tell the main thread that it has stopped. ::SetEvent( m_hProcessStopEvent ); } UINT CFileChangeEvent::MultiFileProcessThread( LPVOID lpParam ) { // This is the threaded multi-file processor. It searches for and processes all raw flight data // (*.FIF files) in the Inbox or until it is cancelled by a call from DataMovement due to // a Cancel message from PC-GBS. CFileChangeEvent* pEvent = (CFileChangeEvent*)lpParam; CFlightDataHandler* pFlightDataHandler = NULL; CLogWriter* pLogWriter = NULL; HANDLE hProcessStopEvent = pEvent->getProcessStopEvent(); HANDLE hProcessRespEvent = pEvent->getProcessRespEvent(); // We use this exception handling merely to protect this service // from being crashed by an unhandled exception. Errors are // generally handled and logged within the DLL by the LogWriter. try { CDataMovement* pDataMovement = pEvent->getDataMovementParent(); CLogWriter* pLogWriter = pDataMovement->getLogWriter(); pFlightDataHandler = new CFlightDataHandler( pLogWriter ); // We must call ::CoInitialize() each time the database is accessed HRESULT hRes = ::CoInitialize(NULL); CString strInboxPath( pDataMovement->getInboxPath() ); vector<CString> vecFifFiles = UtilK::findAllFiles( "*.fif", strInboxPath ); // The input file parameter points to a single *.fif file, but we // need to extract the folder just below the Inbox path so that // all flight data in that path can be processed int nLen = strInboxPath.GetLength() + 1; vector<CString>::iterator iterFile = vecFifFiles.begin(); CString strFile = *iterFile; CString strLastPath = (*iterFile).Mid( 0, strFile.Find( "\\", nLen ) ); int nFileCount = 0; bool bCancelled = false; for( ; iterFile != vecFifFiles.end() && ! bCancelled; iterFile++ ) { CString strPath = UtilK::getFsPart( *iterFile, UtilK::FsPath ); pFlightDataHandler->importRawFlightData( strPath ); DWORD dwWaitStatus = ::WaitForSingleObject( hProcessStopEvent, 1 ); if ( dwWaitStatus == WAIT_FAILED

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

          A couple things I see going on here. 1. You should verify pFlightDataHandler got created before using it. 2. I am assuming that the calls to getProcessStopEvent and getProcessRespEvent actually open a handle, otherwise, when you close them at the end of your thread, you have closed them off for the 'parent' as well. 3. It is not necessary to call AfxEndThread if you are going to exit the thread via its return. Just return the value 0 at end of thread function to accomplish same result. 4. I am assuming that pLogWriter's writeEntry will not throw exceptions, otherwise, you could just flag a problem in your exception handling code and then write to log after leaving the exception. 5. I would consider moving the CoInitialize ahead of your main try block, since the CoUninitialize is already outside of it. 6. If the pFlightDataHandler is a 'risky' object, consider putting its delete in a try/catch block. 7. Why not wait for 0 milliseconds, as per MSDN The function returns if the interval elapses, even if the object's state is nonsignaled. If dwMilliseconds is zero, the function tests the object's state and returns immediately. Then I think it might not even suspend your thread if the system is not busy. Otherwise, I am not sure why you would have a problem, unless one of your obejcts is bad, as there are a couple other retrieval functions there where the pointers are not verified against NULL.

          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