[RESOLVED] How to set a timer for a workthread?
I cerate a workthread for serial port operation. I want the thread to read the serial port once per 100ms, then send the received data to a Dialog.But the thread which install a timer need a message loop,the work thread hasn't it's own message queue.How to slove the problem?
Thanks!
Re: How to set a timer for a workthread?
Quote:
Originally Posted by tjuzhangrui
But the thread which install a timer need a message loop,the work thread hasn't it's own message queue.
Implement the message queue yourself.
Re: How to set a timer for a workthread?
Quote:
Originally Posted by PadexArt
Implement the message queue yourself.
... to transform it in a GUI thread.
Re: How to set a timer for a workthread?
You don't need a timer to read/send your data from serial port.
After the using of CreateFile() function you need to configure the COMMTIMEOUTS structure.
Code:
// Set the Timeouts to specify the behavior of reads and writes.
COMMTIMEOUTS ct;
ct.ReadIntervalTimeout = 100;
ct.ReadTotalTimeoutMultiplier = 0;
ct.ReadTotalTimeoutConstant = 0;
ct.WriteTotalTimeoutMultiplier = 10;
ct.WriteTotalTimeoutConstant = 100;
if (!SetCommTimeouts(hGPSPort, &ct))
{
AfxMessageBox(L"Error Setting Comm Timeouts.", MB_OK, 0);
CloseHandle(hGPSPort);
hGPSPort = INVALID_HANDLE_VALUE;
}
If you need to send your read data from your serial read thread to the main thread (the dialog's thead) you need to define a own message and to use PostMessage(method).
Code:
// in the top of CPP file
#define MY_THREAD_MSG WMAPP + 1
--------
// in the message map
ON_MESSAGE(MY_THREAD_MSG, OnStringPosted)
------------
/* Post the message from thread */
void CyourProgramDlg::PostTheMessage(LPCTSTR pszText)
{
PostMessage(MY_THREAD_MSG, 0, (LPARAM) pszText);
}
-----------
LRESULT CyourProgramDlg::OnStringPosted( WPARAM wParam, LPARAM lParam)
{
CString strLine=_T("");
strLine.Format(_T("%s\r\n"), (LPCTSTR)lParam);
int nLength = m_ctrlLogFile.GetWindowTextLengthW();
m_ctrlLogFile.SetSel(nLength, nLength);
m_ctrlLogFile.ReplaceSel((LPCTSTR)lParam);
return 0;
}
Enjoy! :thumb:
Re: How to set a timer for a workthread?
Quote:
Originally Posted by ovidiucucu
... to transform it in a GUI thread.
No, just to handle the interesting messages. :)
Re: How to set a timer for a workthread?
Quote:
Originally Posted by PadexArt
No, just to handle the interesting messages. :)
Everytime I made a GUI thread I handled only the interesting messages... :D ;)
Re: How to set a timer for a workthread?
Wouldn't it be enough to use
?
Re: How to set a timer for a workthread?
Using MSComm ActiveX could solve many problems.
Re: How to set a timer for a workthread?
Quote:
Originally Posted by tjuzhangrui
I want the thread to read the serial port once per 100ms, then send the received data to a Dialog.But the thread which install a timer need a message loop,the work thread hasn't it's own message queue.How to slove the problem?
Quote:
Originally Posted by Maximus
After the using of CreateFile() function you need to configure the COMMTIMEOUTS structure.
Quote:
Originally Posted by MSDN
ReadIntervalTimeout
Maximum time allowed to elapse between the arrival of two bytes on the communications line, in milliseconds. During a ReadFile operation, the time period begins when the first byte is received. If the interval between the arrival of any two bytes exceeds this amount, the ReadFile operation is completed and any buffered data is returned. A value of zero indicates that interval time-outs are not used.
WriteTotalTimeoutConstant
Constant used to calculate the total time-out period for write operations, in milliseconds. For each write operation, this value is added to the product of the WriteTotalTimeoutMultiplier member and the number of bytes to be written.
Thus, I don't think that's going to help the problem here.
Quote:
Originally Posted by Padan
Wouldn't it be enough to use?
An interesting suggestion...
Quote:
Originally Posted by tjuzhangrui
But the thread which install a timer need a message loop,the work thread hasn't it's own message queue.
So what about making it a GUI thread?
Re: How to set a timer for a workthread?
Quote:
Originally Posted by tjuzhangrui
I cerate a workthread for serial port operation. I want the thread to read the serial port once per 100ms, then send the received data to a Dialog.But the thread which install a timer need a message loop,the work thread hasn't it's own message queue.How to slove the problem?
Quote:
Originally Posted by cilu
Thus, I don't think that's going to help the problem here.
So what about making it a GUI thread?
Marius (cilu), from tjuzhangrui's problem I understand that he has an application with two thread, the main thread for the application dialog and the second for serial port reading.
First, he asks us how he can read the serial port once per 100 ms and I recomanded him to use COMMTIMEOUTS structure in the function of the second thread.
The second part of tjuzhangrui's problem it's the data sending to the main thread (on the dialog).
So, why my advices doesn't helps him on this problem?
Re: How to set a timer for a workthread?
using the sleep will suffice ..
Re: How to set a timer for a workthread?
Quote:
Originally Posted by AshokParikh
Using MSComm ActiveX could solve many problems.
Yeah right :D That thing was designed with VB6 in mind. I wouldn't use it unless I had a gun pointed at my head. Besides, using ActiveX implies a lot of overhead that cannot be justified in this case.
Re: How to set a timer for a workthread?
Thanks All!
I think that Sleep() will be a good solution for my problem.
Re: How to set a timer for a workthread?
Quote:
Originally Posted by Maximus_X
You don't need a timer to read/send your data from serial port.
After the using of CreateFile() function you need to configure the COMMTIMEOUTS structure.
Code:
// Set the Timeouts to specify the behavior of reads and writes.
COMMTIMEOUTS ct;
ct.ReadIntervalTimeout = 100;
ct.ReadTotalTimeoutMultiplier = 0;
ct.ReadTotalTimeoutConstant = 0;
ct.WriteTotalTimeoutMultiplier = 10;
ct.WriteTotalTimeoutConstant = 100;
if (!SetCommTimeouts(hGPSPort, &ct))
{
AfxMessageBox(L"Error Setting Comm Timeouts.", MB_OK, 0);
CloseHandle(hGPSPort);
hGPSPort = INVALID_HANDLE_VALUE;
}
If you need to send your read data from your serial read thread to the main thread (the dialog's thead) you need to define a own message and to use PostMessage(method).
Code:
// in the top of CPP file
#define MY_THREAD_MSG WMAPP + 1
--------
// in the message map
ON_MESSAGE(MY_THREAD_MSG, OnStringPosted)
------------
/* Post the message from thread */
void CyourProgramDlg::PostTheMessage(LPCTSTR pszText)
{
PostMessage(MY_THREAD_MSG, 0, (LPARAM) pszText);
}
-----------
LRESULT CyourProgramDlg::OnStringPosted( WPARAM wParam, LPARAM lParam)
{
CString strLine=_T("");
strLine.Format(_T("%s\r\n"), (LPCTSTR)lParam);
int nLength = m_ctrlLogFile.GetWindowTextLengthW();
m_ctrlLogFile.SetSel(nLength, nLength);
m_ctrlLogFile.ReplaceSel((LPCTSTR)lParam);
return 0;
}
Enjoy! :thumb:
Thanks!
Your method that processing the message is valuable for me.
Re: How to set a timer for a workthread?
Quote:
Originally Posted by Maximus_X
Code:
// ....
/* Post the message from thread */
void CyourProgramDlg::PostTheMessage(LPCTSTR pszText)
{
PostMessage(MY_THREAD_MSG, 0, (LPARAM) pszText);
}
This won't work reliably, since the pointer being posted in the message will not necessarily point to anything meaningful by the time the message is handled. For example:
Code:
//...
{
CString str;
str.Format("Hi from a thread");
PostTheMessage( str ):
}
// str now goes out of scope and is destroyed ...
Since str has gone out of scope, and has been destroyed, by the time that the message handler is executed, the LPARAM of the handler will be pointing to invalid memory. Bad things follow.
Mike