簡體   English   中英

處理 TCP 在不同線程中讀取的 Socket 數據

[英]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.

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