最近完成了数据的读和写。读是用Timer每100ms触发一次,将数据打包,加入校验值,并发送;在data_received事件里进行数据的校验,判断正误,触发一次主窗口的进度条更新事件;发送完整个数据表,触发一次主窗口的数据显示更新。写是,先暂停读,然后将数据打包,加入校验值,发送,线程Sleep(50),同样在data_received事件里进行数据的校验,判断正误,置一个状态标识为写正确还是错误,主程序查询状态标识返回写正确还是错误给与提示。这些基本实现了,能正确读和写,但是我感觉到写的方法是有问题的,因为程序的流程应该不会按照我想的:发送->数据接收校验、置状态标识->主程序提取状态标识并显示。现在我也开始怀疑到底要不要用data_received来做数据的接收,因为它是自动触发的,引起我所有的发送事件都会触发它,而对于不同模式我又要识别需要做一些判断。不知道是不是所有的都应该用:发送->等待->接收(直接用ReadExisting)->主程序显示,这样的模式来做。而且新的问题,让我一定得考虑这个问题,在读里,我最低只能设置Timer的触发事件为70ms,而对于我下面要做的图像显示,这太慢了。我知道,一方面,波特率是个问题,我现在下位机通信速率为9600bps。理论上来说1s钟应该可以发送1200byte,而我通信的包其实只有16个byte,理论上说,1s钟是可以发送几轮的吧,但是不知道该怎么使用它,才能达到最快的时间。以前我想的是直接在data_received里来做数据的打包和发送,但是,data_received好像不那么稳定,而且我不知道它触发的时间,无法预测,看到它是serialPort的辅助线程,听别人说,不要在它里面做太多东西,看别人写的程序是直接弃掉它不用,而用等待接收的方法。我不知道如何是好,但是看别人已经成型的程序,图像数据的采集周期是0.125ms,对于我像天文数字,因为用Timer,我用50ms触发,程序就会卡死,求大神指导!!!静等C#通信多线程

解决方案 »

  1.   

    首先,收数据和处理数据是不应该放在一起,分两部分来做,但是其中不就又多了数据的传递,这个不也是时间吗?其实我不知道你说的数据处理是指什么,在数据接收里面做校验,其实只是判断接收的第1、2位的数值而已,其他的数据都是在Timer里的EventHandler里触发的。还有,通信模块不应该关心上层处理的速度,Timer和data_received都是另开的线程(其实现在程序跑起来线程数有点多),并不影响主窗口的运行啊。卡死,是在通信里面,而我想的以何种方式,提高通信的效率,我自己的逻辑有问题,但是不知道,怎么样的是好的
      

  2.   

    public static Queue<byte> fifoData = new Queue<byte>(1);
    thdFIFO = new Thread(new ThreadStart(readFifoData));
                    thdFIFO.Start();
    private static void readFifoData()
            {
                try
                {
                    int count = 0;
                    SerialPort port = new SerialPort();
                    port.StopBits = StopBits.One;
                    port.DataBits = 8;
                    port.ReadBufferSize = 0x1000;
                    port.WriteBufferSize = 0x1000;
                    port.BaudRate = PublicData.ComBaudRate;
                    port.PortName = PublicData.ComName.ToUpper();
                    port.Open();
                    while (active)
                    {
                        try
                        {
                            count = port.BytesToRead;
                            if (count > 0)
                            {
                                byte[] buffer = new byte[count];
                                port.Read(buffer, 0, count);
                                lock (thisLock)
                                {
                                    for (int i = 0; i < count; i++)
                                    {
                                        fifoData.Enqueue(buffer[i]);
                                    }
                                    count = 0;
                                }
                            }
                            Thread.Sleep(5);
                        }
                        catch
                        {
                        }
                    }
                    port.Close();
                    port.Dispose();
                }
                catch
                {
                    
                }
            }
    再开个线程处理fifoData的数据
    包头包尾协议定好
      

  3.   

    我不知道怎么分开,现在是用的EventHandler触发事件,事件里进行界面更新,这样可以吗?还是有其他的办法?
      

  4.   

    其实说到刷新,也还是有问题的。在我的程序里,每读完一次数据表里的内容,就进行一次数据的刷新,数据的刷新就是将新的数据放到我datagridview中相应显示的地方。问题是现在用户除了有进度条的变化,知道界面在刷新外,其他根本看不出有数据的刷新,我想问,要想用户能看到具体数据有在更新变化,难道进行读一个数,刷新一个数,会不会效率太低下了???