Click here to Skip to main content
15,888,527 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello ,
I have a serious problem
In all of my "CWinThread" classes, I have used "Timer Function" as written below
but after a will (hours) timer stopped without any error!!!
why!!? help me!

// --------------------------------------------------------
// create CManager thread
BOOL CMyDialog::CreateThreads()
{
	// --- // Manager Thread
	m_pManagerThread = AfxBeginThread(RUNTIME_CLASS(CManager), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
	if ( !m_pManagerThread )
	{
		AfxMessageBox("Error at create CManager !!!", MB_ICONERROR);
		return bRet;
	}
	else
	{
		SetThreadAffinityMask(m_pManagerThread->m_hThread, CGlobal_Var::TAFM_MGT);
		m_pManagerThread->m_pMainWnd = this;
		m_pManagerThread->ResumeThread();
		TRACE("Create manager thread."NL);
	}
}	
	
// --------------------------------------------------------
// .h

const int IDT_REFRESH = WM_USER+1 + 72
const int TIMER_DEWILL_TIME = 100; // 100 mili sec

class CManager : public CWinThread
{
	DECLARE_DYNCREATE(CManager)
protected:
	CManager();									// protected constructor used by dynamic creation
	
	CWnd* m_pMainFrame;							// main frame
	
	// timer
	static VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT uIDEvent, DWORD dwTime); 
	void TimerFunc(UINT uIDEvent);				// timer function
	UINT m_iIDTimer;							// timer id
	
	...
	...
	
}

// --------------------------------------------------------
// .cpp
BOOL CManager::InitInstance()
{
	// TODO:  perform and per-thread initialization here
	m_pMainFrame	= m_pMainWnd;
	m_pMainWnd		= NULL;
	
	m_bInit = CreateThreads();
	
	TimerFunc(IDT_REFRESH);
	m_iIDTimer = ::SetTimer(NULL,IDT_REFRESH,TIMER_DEWILL_TIME,TimerProc);
	
	return TRUE;
}

int CManager::ExitInstance()
{
	::KillTimer(NULL,m_iIDTimer);
	PostQuitMessage(0);
	
	return CWinThread::ExitInstance();
}

VOID CALLBACK CManager::TimerProc(HWND hwnd, UINT uMsg, UINT uIDEvent, DWORD dwTime)
{
	CManager* pthread = (CManager*)AfxGetThread();
	if (pthread)
	{
		if (::KillTimer(NULL,uIDEvent))
		{
			pthread->TimerFunc(uIDEvent);
			pthread->m_iIDTimer = ::SetTimer(NULL,IDT_REFRESH,TIMER_DEWILL_TIME,TimerProc);
		}
		else
			TRACE("killtimer failed"NL);
	}
}

void CManager::TimerFunc(UINT uIDEvent)
{
	TRACE(">CManager::TimerFunc %i"NL, uIDEvent);

	// ... Processing or checking 
	
	TRACE("<CManager::TimerFunc"NL);
}
Posted
Updated 16-Oct-11 5:18am
v3
Comments
mohammadmot 17-Oct-11 13:21pm    
For more information:
If I have 2 timer function,
If one of them stopped!
then break-point in another timer (that is running) and start command for stopped timer,
then stopped timer re-start again !!!!

You are using IDT_REFRESH as the ID for all the timers you are starting. The SetTimer[^] documentation states that when you call the SetTimer with an existing timer ID the existing timer will be replaced.

So when a second instance of your CManager class is created the timer created for the first instance is replaced. If you want to create a new timer for each instance of CManager use the following call to create a timer.
C++
pthread->m_iIDTimer = ::SetTimer(NULL,0,TIMER_DEWILL_TIME,TimerProc);
 
Share this answer
 
Comments
mohammadmot 19-Oct-11 5:46am    
Thank you,
I change all of my CWinThread SeTimer uIDEvent to 0, but it keeps happening (timer stopped)!!!!
(In debug or Release mode it's happen!)

I have 2 cwinthread class CManager and CSocketManager, some times it's happen in manager but some times in socket manager thread!
André Kraak 19-Oct-11 15:06pm    
So much for my brilliant idea. :(

It should not be possible but you might want to check whether the timers do use/get the same timer id.
I change my code with this code and no error or TRACEs happen!!!
Although the timer after a will (hours) stopped !
// timer
VOID CALLBACK CManager::TimerProc(HWND hwnd, UINT uMsg, UINT uIDEvent, DWORD dwTime)
{
	CManager* pthread = (CManager*)AfxGetThread();
	if (pthread)
	{
		if (::KillTimer(NULL,pthread->m_iIDTimer/*uIDEvent*/) != 0) // If the function succeeds, the return value is nonzero
		{
			pthread->TimerFunc(pthread->m_iIDTimer/*uIDEvent*/);
			pthread->m_iIDTimer = ::SetTimer(NULL,IDT_REFRESH,TIMER_DEWILL_TIME,TimerProc);
						
			if (pthread->m_iIDTimer == 0)
			{
				// If the function fails to create a timer, the return value is zero
				TRACE("SetTimer failed"NL);
				DWORD dErr = GetLastError();
			}
		}
		else
		{
			// If the function fails, the return value is zero
			TRACE("killTimer failed"NL);
			DWORD dErr = GetLastError();
		}
	}
}

void CManager::TimerFunc(UINT uIDEvent)
{
	if (m_iIDTimer != uIDEvent)
	{
		TRACE("-----------Error on CManager");
	}
	TRACE(">CManager::TimerFunc %i"NL, uIDEvent);

	// ....
}


// ----------------------------------
For more information see [MSDN help about SetTimer] below:
SetTimer
The SetTimer function creates a timer with the specified time-out value.

UINT SetTimer(
HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure
);

Parameters
hWnd
Handle to the window to be associated with the timer. This window must be owned by the calling thread. If this parameter is NULL, no window is associated with the timer and the nIDEvent parameter is ignored.
nIDEvent
Specifies a nonzero timer identifier. If the hWnd parameter is NULL, this parameter is ignored.
uElapse
Specifies the time-out value, in milliseconds.
lpTimerFunc
Pointer to the function to be notified when the time-out value elapses.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900