[英].NET CORE(on windows), DataReceived called frequency of one serialPort effected by other serialPort
我有一個.NET CORE 2.1控制台應用程序,它通過2個comPort(rs232)與2 half-duplex
設備進行通信。
兩個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, 設備A的DataReceived
(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.