OnTimer执行时间与SetTimer设立不一致

OnTimer执行时间与SetTimer设置不一致
用OnTimer循环做相机图像采集,用SYSTEMTIME看了一下执行时间。抓取图像和显示大概用时100ms,但是整个OnTimer循环大概要一秒多才执行一次,导致抓取的图像帧率很低。
SetTimer设置的是100ms,为什么会这样?

另外再问下,有什么好办法做循环抓取图像?

SetTimer设置:
SetTimer(1,100,NULL);


OnTimer函数:

void CcvImgDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

if( nIDEvent == 1 )
{

if( g_iImgSrc == IMG_SRC_IMAGE )
{

}

SYSTEMTIME st;
// GetLocalTime( &st );
CString strTime;

if( g_iImgSrc == IMG_SRC_CAMERA )
{


#ifndef _BAS_CAM_
#define _BAS_CAM_
//定义相机对象
c_BaslerCamera camera;
#endif

if( m_check_lock_file == TRUE)
{
g_bcamPlay = FALSE;
}
else if( m_check_lock_file == FALSE)
{
g_bcamPlay = TRUE;
}


if( g_bcamPlay == TRUE )
{

//如果相机打开失败
if( !camera.Open())
{
g_iImgSrc = 0;
}

//g_bcamPlay = TRUE;
GetLocalTime( &st );
strTime.Format("%d.%d.%d",st.wMinute,st.wSecond,st.wMilliseconds);
sendMSG( "预抓"+strTime );
//抓取单张图片
camera.GrabSingle();

//复制图片
img = cvCloneImage( camera.imgSrc );

//
showImage( img, IDC_SHOW_IMAGE );
GetLocalTime( &st );
strTime.Format("%d.%d.%d",st.wMinute,st.wSecond,st.wMilliseconds);
sendMSG( "显示完成"+strTime );

}
}

}

CDialogEx::OnTimer(nIDEvent);
}

------解决思路----------------------
WM_TIMER本身就是一个优先级非常低的消息, 只有当队列中没有其它消息才会响应WM_TIMER.
而你的WM_TIMER中做了非常耗时的操作, 又卡住了消息队列, 时间就会更长. 
采集应该放到线程中进行, 并且也不保证就可能100ms能采集一次, 要看采集一次数据需要多久才能决定一个最快速度.

比如你采集一帧就需要1秒, 那么你不管怎么样都不可能达到100ms采一帧.
------解决思路----------------------
定时器本身会严重的影响数据采集速度,所以,一般都使用多线程。
------解决思路----------------------
引用:
WM_TIMER本身就是一个优先级非常低的消息, 只有当队列中没有其它消息才会响应WM_TIMER.
而你的WM_TIMER中做了非常耗时的操作, 又卡住了消息队列, 时间就会更长. 
采集应该放到线程中进行, 并且也不保证就可能100ms能采集一次, 要看采集一次数据需要多久才能决定一个最快速度.

比如你采集一帧就需要1秒, 那么你不管怎么样都不可能达到100ms采一帧.

同意,这种比较耗时的东西,单独开辟一个线程,在线程里去处理,Ontimer里只响应功能就行了
------解决思路----------------------
在OnTimer函数中起始位置增加如下代码:
#ifdef DEBUG
CTime timeRecorder;
CString strTimeCur;
timeRecorder = CTime::GetCurrentTime();
strTimeCur = timeRecorder.Format("%X");
TRACE("Enter  OnTimer( ): %s\n",strTimeCur);
#endif
 
在OnTimer函数中结束位置增加如下代码:
#ifdef DEBUG
timeRecorder = CTime::GetCurrentTime();
strTimeCur = timeRecorder.Format("%X");
TRACE("Leave OnTimer( ): %s\n",strTimeCur);
#endif
 
可以实际计算每次抓取图片耗费了多长时间. 如果时间大于100ms,那么定时器产生的消息,应用程序并不能马上取出来,你要知道应用程序主线程其实是一个死循环,从主线程消息队列中取出一条消息,处理该条消息,然后取下一条消息,一直循环下去..... 它不会一条消息没处理完就去消息队列中去取下一条消息。如果允许这样做的话,那代码执行路径将无法预计和控制。