簡體   English   中英

.NET CORE(在Windows上),DataReceived稱為一個串行端口的頻率,該頻率由其他串行端口影響

[英].NET CORE(on windows), DataReceived called frequency of one serialPort effected by other serialPort

我有一個.NET CORE 2.1控制台應用程序,它通過2個comPort(rs232)與2 half-duplex設備進行通信。

  • COM1上的設備A,波特率9600,我的應用每200毫秒輪詢一次,並在50毫秒內獲得響應。
  • COM2上的設備B,波特率1200,我的應用程序每400毫秒接收一次輪詢,並在50毫秒內響應。

兩個comPort的代碼完全分開 ,沒有共享變量,沒有引用等。

對於設備A:

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:

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, 設備ADataReceived (comPort1)將被隨機延遲調用(從ms到秒),在延遲期間,設備A的200ms輪詢永不停止,所以我“會突然在一個得到設備龐大的數據DataReceived

誰能幫忙,為什么這兩個通信相互影響?

-----更多測試----

我進行了一項測試,將3個comPort中的3個設備A連接到應用程序中,它們工作良好,沒有DataReceived延遲。

經過一些測試和從Web發布后,我在.NET CORE上確認了此行為,多次SerialPort寫和接收可能會延遲DataReceived的觸發,因此,我沒有等待,而是添加了一個代碼來主動拉

    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");
        }
    }

從我的測試來看,問題已經解決了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM