首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET核心(在windows上),DataReceived调用受其他serialPort影响的一个serialPort的频率

.NET核心(在windows上),DataReceived调用受其他serialPort影响的一个serialPort的频率
EN

Stack Overflow用户
提问于 2018-11-27 20:38:55
回答 1查看 184关注 0票数 0

我有一个.NET核心2.1控制台应用程序,它通过2 comPort (rs232)与两个设备进行通信,这两个设备都是half-duplex

  • COM1上的设备A,波特率9600,我的应用程序每200毫秒轮询一次,在50毫秒内得到响应。
  • 在COM2上的设备B,波特率1200,我的应用程序每400毫秒收到它的投票,并在50毫秒内响应它。

两个comPort的代码是完全分离的,没有共享变量,没有引用等等。

对于设备A:

代码语言:javascript
复制
private ConcurrentQueue<object> outgoingMessageQueue = new ConcurrentQueue<object>();
this.comPort1.DataReceived += (a,b)=>{
    while (this.comPort1.BytesToRead > 0){
        var b = this.comPort.ReadByte();
        buffer.Add((byte)b);
    };
    if(CheckIsFullMessage(buffer))
    {//fire event for consume}

};
ThreadPool.QueueWorkerThread((_)=>{
while(true){
    Thread.Sleep(200); 
    if (this.outgoingMessageQueue.TryDequeue(out object pendingForWrite))
    {this.comPort1.Write(pendingForWrite); }
    else
        this.comPort1.Write(new PollMsg());
}};
//business logic, queue a request at any time.
this.outgoingMessageQueue.Add(new requestMessage()); 

对于设备B:

代码语言:javascript
复制
this.comPort2.DataReceived += (a,b)=>{
    while (this.comPort2.BytesToRead > 0){
        var b = this.comPort.ReadByte();
        buffer.Add((byte)b);
    };
    if(CheckIsFullMessage(buffer))
    {
      //trigger business logic, consume the buffer and construct a response.
      //this.comPort2.Write(response,0,response.length); 
    }       
};

我注意到一件事,如果我打开设备B,DataReceived for device A (comPort1)将是,延迟调用(从ms到秒),在延迟期间,设备A的200 ms轮询永远不会停止,所以我会突然从one DataReceived的设备A获得大量数据。

有人能帮忙吗,为什么这两个comPorts互相影响?

-更多的测试

我做了一个测试,将3 comPort中的3台设备A连接到app中,它们工作得很好,没有DataReceived延迟。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-21 04:13:28

经过一些测试和发布后,我在.NET内核上确认了这种行为,多个SerialPort写和接收可能会延迟DataReceived的触发,所以我没有等待,而是向主动拉添加了一个代码

代码语言:javascript
复制
    public void Start()
    {
        this.comPort.DataReceived += (_,__)=>{this.PullPortDataBuffer();};
        //for very fast time accurate call(my app send&receive data every 200ms), use dedicated thread rather than timer.
        this.pullingSerialPortBufferLoop = new Thread(() =>
        {
            while (true)
            {                
                Thread.Sleep(200);
                this.PullPortDataBuffer();
            }
        });
        this.pullingSerialPortBufferLoop.Start();
    };
    var buffer = new List<byte>();
    private void PullPortDataBuffer()
    {
        if (0 == Interlocked.CompareExchange(ref this.onPullingComPortBuffer, 1, 0))
            try
            {

                while (this.comPort.BytesToRead > 0)
                {                        
                    this.buffer.Add((byte)b);
                }

                this.ConsumeBufferIfFull(this.buffer);
            }
            catch (Exception ex)
            {}
            finally
            {
                this.onPullingComPortBuffer = 0;
            }
        else
        {
            if (logger.IsDebugEnabled)
                logger.Debug(this.comPort.PortName + " concurrent enter Port_DataReceived");
        }
    }

从我的测试来看,这个问题已经解决了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53507757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档