关于如何确保一个成员函数每隔一定时间就执行一次的问题,这个不是简单的SetTimer问题。
需求是这样的: 1.程序要求每隔15秒读取一次数据。实际是该时间间隔必须在10秒与20秒之间,取了中间的15;
2.将读取的数据写入新文件中,并根据读取的时间作为文件名。将该文件名保存到表中,用于在步骤3中调用;
3.从表中读取新生成的数据文件名称,打开文件,将该文件内容按一定的规则进行处理。 以上1、2、3是完成一次处理所需的流程顺序。要求对读取到的数据的后续的处理不能影响每隔15秒读一次数据,也就是说,无论后续数据处理怎么耗时,都必须确保每隔15秒读取一次数据,最迟不能超过20秒(15秒内肯定能把数据读完并保存到新文件中,这不是问题)。
关键是第三步对新文件的处理非常复杂,是个while循环,导致非常耗时。请朋友们不要关注怎样改进文件处理规则来提高处理时间,规则是固定的,不能改,每次处理至少5分钟才能完成。所以问题由此而来,怎么样让数据处理不干扰数据读取,也就是说把这两个过程独立起来,各执行各的。已采取的方案有:
方案1:使用计时器。创建两个计时器,计时器1用于读数据,时间间隔为15秒;计时器2用于处理数据,时间间隔为7分钟。
该方案的问题是当处理数据时while循环会导致程序的窗口点击无法响应,象死机一样,同样也导致计时器1发出的WM_TIMER消息被阻塞,即整个处理数据期间根本无法读取数据,导致读取数据严重超时。 方案2:只创建一个计时器,用于处理数据。而读取数据则使用COleDateTime类与COleDateTimeSpan类结合while循环来计时。例如: while(bIsOK) //bIsOK用于控制循环退出
{
//设定循环时间间隔为15秒
int nInterval = 15
//开始时间,用于计算延时
COleDateTime tStart = COleDateTime::GetCurrentTime(); //开始读数据
ReadData(); //计算耗时
COleDateTimeSpan tsSecond = COleDateTime::GetCurrentTime() - tStart;
int nSeconds = tsSecond.GetTotalSeconds();
//开始延时。只要从读数据开始到现在未达到15秒就延时,直到达到15秒再退出延时,
while(bIsOK && nSeconds < nInterval)
{
//计算剩余的延迟时间
tsSecond = COleDateTime::GetCurrentTime() - tStart;
nSeconds = tsSecond.GetTotalSeconds();
//每2秒进行一次消息循环,否则窗口无法响应用户操作。
if(nSeconds%2 == 0 && ::GetMessage(&msg,NULL,0,0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
该方案的问题是:因为在延时中加入了消息处理,而有的消息处理会耗费时间,所以延时经常不准确。不加消息处理时延时是非常精确的,但不加消息处理时程序窗口无法响应,象死机了一样。问题就是这样了,请朋友们帮忙解决一下。尽量不要创建线程以在线程中进行数据处理。我希望能使用一种办法确保无论系统多么繁忙或被阻塞,总能保证每隔15秒执行一次读数据的成员函数。
需求是这样的: 1.程序要求每隔15秒读取一次数据。实际是该时间间隔必须在10秒与20秒之间,取了中间的15;
2.将读取的数据写入新文件中,并根据读取的时间作为文件名。将该文件名保存到表中,用于在步骤3中调用;
3.从表中读取新生成的数据文件名称,打开文件,将该文件内容按一定的规则进行处理。 以上1、2、3是完成一次处理所需的流程顺序。要求对读取到的数据的后续的处理不能影响每隔15秒读一次数据,也就是说,无论后续数据处理怎么耗时,都必须确保每隔15秒读取一次数据,最迟不能超过20秒(15秒内肯定能把数据读完并保存到新文件中,这不是问题)。
关键是第三步对新文件的处理非常复杂,是个while循环,导致非常耗时。请朋友们不要关注怎样改进文件处理规则来提高处理时间,规则是固定的,不能改,每次处理至少5分钟才能完成。所以问题由此而来,怎么样让数据处理不干扰数据读取,也就是说把这两个过程独立起来,各执行各的。已采取的方案有:
方案1:使用计时器。创建两个计时器,计时器1用于读数据,时间间隔为15秒;计时器2用于处理数据,时间间隔为7分钟。
该方案的问题是当处理数据时while循环会导致程序的窗口点击无法响应,象死机一样,同样也导致计时器1发出的WM_TIMER消息被阻塞,即整个处理数据期间根本无法读取数据,导致读取数据严重超时。 方案2:只创建一个计时器,用于处理数据。而读取数据则使用COleDateTime类与COleDateTimeSpan类结合while循环来计时。例如: while(bIsOK) //bIsOK用于控制循环退出
{
//设定循环时间间隔为15秒
int nInterval = 15
//开始时间,用于计算延时
COleDateTime tStart = COleDateTime::GetCurrentTime(); //开始读数据
ReadData(); //计算耗时
COleDateTimeSpan tsSecond = COleDateTime::GetCurrentTime() - tStart;
int nSeconds = tsSecond.GetTotalSeconds();
//开始延时。只要从读数据开始到现在未达到15秒就延时,直到达到15秒再退出延时,
while(bIsOK && nSeconds < nInterval)
{
//计算剩余的延迟时间
tsSecond = COleDateTime::GetCurrentTime() - tStart;
nSeconds = tsSecond.GetTotalSeconds();
//每2秒进行一次消息循环,否则窗口无法响应用户操作。
if(nSeconds%2 == 0 && ::GetMessage(&msg,NULL,0,0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
该方案的问题是:因为在延时中加入了消息处理,而有的消息处理会耗费时间,所以延时经常不准确。不加消息处理时延时是非常精确的,但不加消息处理时程序窗口无法响应,象死机了一样。问题就是这样了,请朋友们帮忙解决一下。尽量不要创建线程以在线程中进行数据处理。我希望能使用一种办法确保无论系统多么繁忙或被阻塞,总能保证每隔15秒执行一次读数据的成员函数。
难道没制定这个方案?别执着MFC,消息机制
楼主的文件操作的耗时是不确定的
timer肯定准不了
下面是多线程简单用例,你看一下,不难!
http://download.csdn.net/source/1123495
当然,多线程用的复杂了,还是比较难的!
CreateWaitableTimer
SetWaitableTimer
感谢参与的各位热心的朋友们!
另外,要特别感谢一下钻石cnzdgs,您的参与让这个帖子蓬荜生辉!