[英]Process TCP Socket data read in different thread
我正在開發一個程序以與每 70 毫秒通過 TCP 通道發送數據的設備集成。
我正在使用 Socket.BeginReceive 和 Socket.EndReceive 方法來讀取數據。 邏輯在以下偽代碼中描述
private void OnReceived(IAsyncResult ar)
{
var rcvdDataLength = m_tcpSocket.EndReceive(ar);
Array.Copy(m_tempRecvBuffer, 0, m_mainBuffer, m_mainBufferDataIndex, rcvdDataLength);
if (CheckIfValidHeaderAndBodyReceived())
{
var actualData = new byte[headerLen + BodyLen];
Array.Copy(m_mainBuffer, m_dataIndex, actualData, 0, headerLen + BodyLen);
Process(actualData);
}
m_tcpSocket.BeginReceive(m_tempRecvBuffer, 0, m_tempRecvBuffer.Length, SocketFlags.None,
OnReceived, null);
}
上述代碼中描述的流程function負責實現業務邏輯。 過程 function 目前大約需要 300 毫秒。
所以消費者(需要 300 毫秒)比生產者(每 70 毫秒發布一次數據)慢。 我是否需要異步運行此 Process function 以避免延遲? 還是 TCP 層的流控制方面負責這個?
我是否需要異步運行此 Process function 以避免延遲?
這取決於您的應用程序以及最終您自己的優先級決定。 嚴格來說,不,您不需要異步執行任何操作,但這可能是件好事。
我通常使用和推薦的方法是一個專用於接口的線程,通過隊列與應用程序的rest進行交互。 當通信線程接收到消息時,它會鎖定一個隊列並將它們推入。當主應用程序准備好使用該數據時,它會鎖定該隊列並盡可能多地退出隊列。 這是一個簡單、健壯且可靠的機制。 轉到您的偽代碼:
private void OnReceived(IAsyncResult ar)
{
var rcvdDataLength = m_tcpSocket.EndReceive(ar);
Array.Copy(m_tempRecvBuffer, 0, m_mainBuffer, m_mainBufferDataIndex, rcvdDataLength);
if (CheckIfValidHeaderAndBodyReceived())
{
var actualData = new byte[headerLen + BodyLen];
Array.Copy(m_mainBuffer, m_dataIndex, actualData, 0, headerLen + BodyLen);
lock(messageQueue)
{
messageQueue.Enqueue(actualData);
}
}
m_tcpSocket.BeginReceive(m_tempRecvBuffer, 0, m_tempRecvBuffer.Length, SocketFlags.None,
OnReceived, null);
}
然后在你的應用程序的某個地方:
void ProcessQueue()
{
Queue<byte[]> tempQueue = new Queue<byte[]>();
lock(messageQueue)
{
// Drain the queue so we can release the lock ASAP
while(messageQueue.Count > 0)
{
tempQueue.Enqueue(messageQueue.Dequeue());
}
}
while(tempQueue.Count > 0)
{
Process(tempQueue.Dequeue());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.