.NET CORE (на окнах), DataReceived вызывает частоту одного serialPort, вызванного другим serialPort - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть консольное приложение .NET CORE 2.1, которое обменивается данными с двумя устройствами, оба из которых half-duplex через 2 comPort (rs232).

  • устройство A на COM1, скорость передачи 9600,мое приложение опрашивает его каждые 200 мс и получает ответ через 50 мс.
  • устройство B на COM2, скорость передачи 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, DataReceived для устройства A (comPort1) будет случайным образом задерживаться для вызова(от мс до секунд), в течение периода задержки опрос 200 мс устройства А никогда не прекращается, поэтому я неожиданно получу огромные данные с устройства А за один DataReceived.

Может кто-нибудь помочь, почему эти двакоморты влияли друг на друга?

----- еще тест ----

Я провел тест, который соединяет 3 устройства A в 3 comPort в приложение, они работают хорошо, без DataReceived задержки.

1 Ответ

0 голосов
/ 21 декабря 2018

После некоторого тестирования и публикации из Интернета я подтвердил такое поведение в .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");
        }
    }

из моего тестирования, проблема исчезла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...