问:在vc中如何让当前"过程"等待1秒,但消息机制不关闭(不能用Sleep()来处理延时)

时间:2022-10-11 17:20:08
VC中过程函数是这样的.
void func1()
{
   uart_send("一串内容给下位机!");
   ---wait(1000ms);    //此处用什么办法实现, 使用sleep(1000),基于消息的串口也停了
   //下位机接收到上位机发送后到的信息后,返回确认信号,确认信号在PC机的缓冲区中
   
   //PC接收到下位机发送的确认信号
   CString reply = uart_receive();
   if(reply == "通信正确!")
   {
       //上位机执行其它通信操作
   }
   else
   {
       //通信失败
       return;
   }
}

14 个解决方案

#1


用一个死循环,取进入循环时间,如果当前时间与进入循环时间差大于1000ms,就退出循环体

#2


在windows消息机制下,更合理的办法是设定一个定时器,1秒后触发,而不是在那里延时

#3


引用 2 楼 arong1234 的回复:
在windows消息机制下,更合理的办法是设定一个定时器,1秒后触发,而不是在那里延时


这个说的很对,VC下的定时器1秒误差不是很大,楼主可以试试!

#4


引用 1 楼 thefirstz 的回复:
用一个死循环,取进入循环时间,如果当前时间与进入循环时间差大于1000ms,就退出循环体


感觉这样跟sleep没区别 甚至效率更低

#5


timer是正解,1楼的方法循环里面要加消息分发

#6


还是我来说吧,自己模拟消息分发

dispathmes
transfermes

#7


1秒钟的话,sleep 也关系不大,UI 体验差别很有限的。

#8


Sleep()是不能用的,原因是一当程序进入Sleep()后,等醒来的时候,串口什么东西也没有收到,我估计Sleep()是彻底地停掉了整个程序。

 ---正常程序---
 SetTimer(2, 1000, NULL);
 bTimer2 = FALSE;
 while(bTimer2 == FALSE);
 ---正常程序---

然后我在OnTimer()中设置一个消息分支, 将序号为2的定时器的功能设置为:bTimer2 = TRUE;

但是while(bTimer2 == FALSE);//永远都无法执行完,死循环。它好像感应不到外界对bTimer2的更改。
我用C里的volatile关键字试试看。

#9


volatile好像也没有起到什么作用。

#10


引用 6 楼 bloodfighter 的回复:
还是我来说吧,自己模拟消息分发

dispathmes
transfermes

我觉得这个方法应该可行,毕竟需求是简单的,如果因为这个需求,就修改软件的整体设计,就不值得了

void func1()
{
   time_t nBeginTime = CTime::CurrentTime();
   localtime(&nBeginTime);

   uart_send("一串内容给下位机!");
  ---wait(1000ms); //此处用什么办法实现, 使用sleep(1000),基于消息的串口也停了
  while(1)
  {
     time_t nTime;
     localtime(&nTime);
     if(nTime > nBeginTime+1)
           break;
     MSG msg; 
     
     while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ 
     if(msg.message==WM_QUIT) 
     return FALSE; 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
  };
  //下位机接收到上位机发送后到的信息后,返回确认信号,确认信号在PC机的缓冲区中
    
  //PC接收到下位机发送的确认信号
  CString reply = uart_receive();
  if(reply == "通信正确!")
  {
  //上位机执行其它通信操作
  }
  else
  {
  //通信失败
  return;
  }
}

#11


引用 8 楼 ajddcw 的回复:
Sleep()是不能用的,原因是一当程序进入Sleep()后,等醒来的时候,串口什么东西也没有收到,我估计Sleep()是彻底地停掉了整个程序。

 ---正常程序---
 SetTimer(2, 1000, NULL);
 bTimer2 = FALSE;
 while(bTimer2 == FALSE);
 ---正常程序---

然后我在OnTimer()中设置一个消息分支,……


调试的时候,首先确定bTimer2 = TRUE; 被执行了,

检查bTimer2 时候是全局可见的变量,即必须在func1和OnTimer里这个变量均可见,且是同一个变量。

#12


学习了............

#13


引用 7 楼 demonwhisper 的回复:
1秒钟的话,sleep 也关系不大,UI 体验差别很有限的。

忽视这个。既然是基于消息循环的通讯,那么就设置 flag,然后再消息循环里空等好了。

#14


学习了,各位高手,感谢了!

#1


用一个死循环,取进入循环时间,如果当前时间与进入循环时间差大于1000ms,就退出循环体

#2


在windows消息机制下,更合理的办法是设定一个定时器,1秒后触发,而不是在那里延时

#3


引用 2 楼 arong1234 的回复:
在windows消息机制下,更合理的办法是设定一个定时器,1秒后触发,而不是在那里延时


这个说的很对,VC下的定时器1秒误差不是很大,楼主可以试试!

#4


引用 1 楼 thefirstz 的回复:
用一个死循环,取进入循环时间,如果当前时间与进入循环时间差大于1000ms,就退出循环体


感觉这样跟sleep没区别 甚至效率更低

#5


timer是正解,1楼的方法循环里面要加消息分发

#6


还是我来说吧,自己模拟消息分发

dispathmes
transfermes

#7


1秒钟的话,sleep 也关系不大,UI 体验差别很有限的。

#8


Sleep()是不能用的,原因是一当程序进入Sleep()后,等醒来的时候,串口什么东西也没有收到,我估计Sleep()是彻底地停掉了整个程序。

 ---正常程序---
 SetTimer(2, 1000, NULL);
 bTimer2 = FALSE;
 while(bTimer2 == FALSE);
 ---正常程序---

然后我在OnTimer()中设置一个消息分支, 将序号为2的定时器的功能设置为:bTimer2 = TRUE;

但是while(bTimer2 == FALSE);//永远都无法执行完,死循环。它好像感应不到外界对bTimer2的更改。
我用C里的volatile关键字试试看。

#9


volatile好像也没有起到什么作用。

#10


引用 6 楼 bloodfighter 的回复:
还是我来说吧,自己模拟消息分发

dispathmes
transfermes

我觉得这个方法应该可行,毕竟需求是简单的,如果因为这个需求,就修改软件的整体设计,就不值得了

void func1()
{
   time_t nBeginTime = CTime::CurrentTime();
   localtime(&nBeginTime);

   uart_send("一串内容给下位机!");
  ---wait(1000ms); //此处用什么办法实现, 使用sleep(1000),基于消息的串口也停了
  while(1)
  {
     time_t nTime;
     localtime(&nTime);
     if(nTime > nBeginTime+1)
           break;
     MSG msg; 
     
     while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ 
     if(msg.message==WM_QUIT) 
     return FALSE; 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
  };
  //下位机接收到上位机发送后到的信息后,返回确认信号,确认信号在PC机的缓冲区中
    
  //PC接收到下位机发送的确认信号
  CString reply = uart_receive();
  if(reply == "通信正确!")
  {
  //上位机执行其它通信操作
  }
  else
  {
  //通信失败
  return;
  }
}

#11


引用 8 楼 ajddcw 的回复:
Sleep()是不能用的,原因是一当程序进入Sleep()后,等醒来的时候,串口什么东西也没有收到,我估计Sleep()是彻底地停掉了整个程序。

 ---正常程序---
 SetTimer(2, 1000, NULL);
 bTimer2 = FALSE;
 while(bTimer2 == FALSE);
 ---正常程序---

然后我在OnTimer()中设置一个消息分支,……


调试的时候,首先确定bTimer2 = TRUE; 被执行了,

检查bTimer2 时候是全局可见的变量,即必须在func1和OnTimer里这个变量均可见,且是同一个变量。

#12


学习了............

#13


引用 7 楼 demonwhisper 的回复:
1秒钟的话,sleep 也关系不大,UI 体验差别很有限的。

忽视这个。既然是基于消息循环的通讯,那么就设置 flag,然后再消息循环里空等好了。

#14


学习了,各位高手,感谢了!