2014-10-03 62 views
1

由於我的問題已經接近這個問題,所以我從這個可能的解決方案反饋回來:Reading on a NetworkStream = 100% CPU usage但我找不到我需要的解決方案。讀取.NET流:高CPU使用率 - 如何閱讀wihtout while(true)?

就像在這個其他問題一樣,我想使用別的東西而不是無限的while循環。

更確切地說,我使用XamarinVisual Studio中構建Android應用程序。由於我需要Bluetooth服務,因此我使用Stream來讀取和發送數據。

Stream.InputStrem中讀取數據是我遇到問題的地方:有沒有某種阻塞調用等待數據可用而不使用while(true)循環?

我嘗試:

  • 開始/結束讀
  • Task.Run並等待

下面是一個代碼示例:

public byte[] RetrieveDataFromStream() 
    { 
     List<byte> packet = new List<byte>(); 
     int readBytes = 0; 
     while (_inputStream.CanRead && _inputStream.IsDataAvailable() && readBytes < 1024 && _state == STATE_CONNECTED) 
     { 
      try 
      { 
       byte[] buffer = new byte[1]; 
       readBytes = _inputStream.Read(buffer, 0, buffer.Length); 

       packet.Add(buffer[0]); 
      } 
      catch (Java.IO.IOException e) 
      { 
       return null; 
      } 
     } 
     return packet.ToArray(); 
    } 

我把這種方法從while循環。 此循環將檢查,直到此方法返回NULL以外的其他值,在這種情況下,我將相應地處理數據。

只要有數據需要處理,CPU使用率就會降低,低於沒有數據要處理的情況。

我知道爲什麼我的CPU使用率很高:如果有東西需要讀取,循環會盡可能頻繁地檢查。從好的一面來看,接收數據時幾乎沒有延遲,但不是,這不是一個可行的解決方案。

任何想法來改變這一點?

#更新1

按照馬克Gravell的想法,這裏是我想什麼瞭解和嘗試:

byte buffer = new byte[4096]; 
while (_inputStream.CanRead 
    && (readBytes = _inputStream.Read(buffer, 0, buffer.Length)) > 0 
    && _state == STATE_CONNECTED) 
{ 
    for(int i = 0 ; i < readBytes; i++) 
     packet.Add(buffer[i]); 
    // or better: some kind of packet.AddRange(buffer, 0, readBytes) 
} 

你怎麼稱呼這個代碼片斷? 兩個問題:

  1. 如果沒有要讀取,那麼while條件將是 辭退:下一步該怎麼做?

  2. 一旦你讀完了,你接下來會做什麼?你做什麼來捕獲任何新的傳入數據包?

這裏有一些解釋,應該幫助:

  1. 該機器人裝置被連接,通過藍牙,向發送數據的另一裝置。它會一直髮送一個指定大小的預先設計的數據包(1024)。該設備可以連續流式傳輸數據一段時間,但也可以在任何時間長時間停止。如何處理這種行爲?
+0

當IsDataAvailable()返回false時,存在的主要問題是「熱循環」。坦率地說,你*不需要檢查* - 只是'讀' – 2014-10-03 10:40:50

+0

謝謝。我會考慮它。如果它不「破壞」我的算法並創建一個較小的CPU負載:) – Mackovich 2014-10-03 12:28:05

回答

1

立即解決此問題是:

  • 沒有一次讀一個字節
  • 不創建一個新的緩衝區每字節
  • 不熱的坐循環時沒有可用

例如數據:

byte buffer = new byte[4096]; 
while (_inputStream.CanRead 
    && (readBytes = _inputStream.Read(buffer, 0, buffer.Length)) > 0 
    && _state == STATE_CONNECTED) 
{ 
    for(int i = 0 ; i < readBytes; i++) 
     packet.Add(buffer[i]); 
    // or better: some kind of packet.AddRange(buffer, 0, readBytes) 
} 

請注意,使用readBytes在原來的while檢查看起來有點......困惑;我用「雖然我們沒有得到EOF」檢查取代它;隨時添加您自己的邏輯。

+0

好吧,我已經看過這種模式幾次了,但是......在哪裏以及如何調用它?我會更新我的帖子以更精確。謝謝 – Mackovich 2014-10-03 12:26:45