小弟在做一个485的项目,采用轮询通信方式,遇到一个问题,求指点

nucjankk 2013-08-08 06:47:43
上位机与下位机是主从式通讯方式,下位机由三块仪表构成,上位机采用轮询发送下位机地址的方式,地址的发送放在了一个时间间隔为2000ms的timer定时器内,具体思路上首先发送1#号机地址,然后执行一个延时函数500ms等待(这段时间间隔用来处理串口的serialPort_DataReceived事件以及UI的更新),之后再发送2#机地址,执行延时函数,……。我程序大体是这样写的,但是在调试的时候 刚运行可以收到1#号仪表的数据,之后就再收不到数了,我怀疑是不是在执行500ms延时函数的时候阻塞了线程,才导致这样,不知道这个怀疑对不对,我的上位机采用C#编写,定时器及延时函数如下:请高手给予指导。
       private void timerDraw_Tick(object sender, EventArgs e)
{

if (!serialPort.IsOpen)
{
openPort();
}
string strCMD = "010300040001C5F8";//1号机地址
SendAsHex(strCMD);//十六进制发送
delayMs(500);//

string strCMD2 = "020300040001C429";//2号机地址
SendAsHex(strCMD2);//十六进制发送
delayMs(500);

string strCMD2 = "030300040001C4a3";//3号机地址
SendAsHex(strCMD2);//十六进制发送
delayMs(500);

}

这是延时函数
   private static void delayMs(int DelayTime)
{
int time = Environment.TickCount;
while (true)
{
if (Environment.TickCount - time >= DelayTime)
{
break;
}
Application.DoEvents();
//Thread.Sleep(10);
}
}
...全文
1833 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
feiniao19830822 2013-08-08
  • 打赏
  • 举报
回复
引用 7 楼 nucjankk 的回复:
兄台是Thread.Sleep(500);还是thread.Sleep(500);啊,这后面这种写法对不对,刚才试了一下,后边这种写法有语法错误。前边那种写法程序没有改善呢。
是Thread.Sleep(500); 程序没有改善,原因有很多。 第一你只发送2号机地址,看看有没有接收到返回数据。 第二有可能是等待的时间不够长,可以把500改大一点。
nucjankk 2013-08-08
  • 打赏
  • 举报
回复
兄台是Thread.Sleep(500);还是thread.Sleep(500);啊,这后面这种写法对不对,刚才试了一下,后边这种写法有语法错误。前边那种写法程序没有改善呢。
nucjankk 2013-08-08
  • 打赏
  • 举报
回复
引用 4 楼 u011303459 的回复:
你的timer是System.Windows.Forms.Timer。这种定时器是在主线程执行的。这样延时是会堵住主线程的。 定时器还有另外2种,其中一种是开子线程的,你可以换成它,或者直接开启子线程。

            Thread thread = new Thread(SendData);
            thread.Start();
        
        private void SendData()
        {
            if (!serialPort.IsOpen)
            {
                openPort();
            }
            string strCMD = "010300040001C5F8";//1号机地址
            SendAsHex(strCMD);//十六进制发送
            Thread.Sleep(500);

            string strCMD2 = "020300040001C429";//2号机地址
            SendAsHex(strCMD2);//十六进制发送
            Thread.Sleep(500);

            string strCMD2 = "030300040001C4a3";//3号机地址
            SendAsHex(strCMD2);//十六进制发送
            Thread.Sleep(500);
        }
引用 4 楼 u011303459 的回复:
你的timer是System.Windows.Forms.Timer。这种定时器是在主线程执行的。这样延时是会堵住主线程的。 定时器还有另外2种,其中一种是开子线程的,你可以换成它,或者直接开启子线程。

            Thread thread = new Thread(SendData);
            thread.Start();
        
        private void SendData()
        {
            if (!serialPort.IsOpen)
            {
                openPort();
            }
            string strCMD = "010300040001C5F8";//1号机地址
            SendAsHex(strCMD);//十六进制发送
            Thread.Sleep(500);

            string strCMD2 = "020300040001C429";//2号机地址
            SendAsHex(strCMD2);//十六进制发送
            Thread.Sleep(500);

            string strCMD2 = "030300040001C4a3";//3号机地址
            SendAsHex(strCMD2);//十六进制发送
            Thread.Sleep(500);
        }
多谢兄台指点。
feiniao19830822 2013-08-08
  • 打赏
  • 举报
回复
你的timer是System.Windows.Forms.Timer。这种定时器是在主线程执行的。这样延时是会堵住主线程的。 定时器还有另外2种,其中一种是开子线程的,你可以换成它,或者直接开启子线程。

            Thread thread = new Thread(SendData);
            thread.Start();
        
        private void SendData()
        {
            if (!serialPort.IsOpen)
            {
                openPort();
            }
            string strCMD = "010300040001C5F8";//1号机地址
            SendAsHex(strCMD);//十六进制发送
            Thread.Sleep(500);

            string strCMD2 = "020300040001C429";//2号机地址
            SendAsHex(strCMD2);//十六进制发送
            Thread.Sleep(500);

            string strCMD2 = "030300040001C4a3";//3号机地址
            SendAsHex(strCMD2);//十六进制发送
            Thread.Sleep(500);
        }
  • 打赏
  • 举报
回复
不知道你的timer是怎样创建的。参考http://bbs.csdn.net/topics/370096927 关于什么while循环、Application.DoEvents()这类代码,我不会在所谓线程程序设计中使用。你的程序的我没有什么修改意见,除非你避免循环死等这类语句。
nucjankk 2013-08-08
  • 打赏
  • 举报
回复
引用 1 楼 sp1234 的回复:
业务逻辑上的所谓延时,通常是定时的意思,而不是把系统组塞起来的意思。
我也感觉这样做不是很好,但我没有好的思路,您能给一个吗,我就是想将下位机的三个地址循环依次按一定的时间间隔通过串口发送出去。
  • 打赏
  • 举报
回复
业务逻辑上的所谓延时,通常是定时的意思,而不是把系统组塞起来的意思。
nucjankk 2013-08-08
  • 打赏
  • 举报
回复
引用 8 楼 u011303459 的回复:
[quote=引用 7 楼 nucjankk 的回复:] 兄台是Thread.Sleep(500);还是thread.Sleep(500);啊,这后面这种写法对不对,刚才试了一下,后边这种写法有语法错误。前边那种写法程序没有改善呢。
是Thread.Sleep(500); 程序没有改善,原因有很多。 第一你只发送2号机地址,看看有没有接收到返回数据。 第二有可能是等待的时间不够长,可以把500改大一点。 [/quote] 将时间改成1000ms,已经可以收到数了。多谢。
leafmao 2013-08-08
  • 打赏
  • 举报
回复
阻塞线程不大可能,timer跟SerialPort_DataReceived是不同的线程。 如果完全没接收到数据,可能是下位机没发送数据过来

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧