由于我的问题已经接近这个问题,所以我从这个可能的解决方案反馈回来:Reading on a NetworkStream = 100% CPU usage但我找不到我需要的解决方案。读取.NET流:高CPU使用率 - 如何阅读wihtout while(true)?
就像在这个其他问题一样,我想使用别的东西而不是无限的while循环。
更确切地说,我使用Xamarin
在Visual 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)
}
你怎么称呼这个代码片断? 两个问题:
如果没有要读取,那么while条件将是 辞退:下一步该怎么做?
一旦你读完了,你接下来会做什么?你做什么来捕获任何新的传入数据包?
这里有一些解释,应该帮助:
- 该机器人装置被连接,通过蓝牙,向发送数据的另一装置。它会一直发送一个指定大小的预先设计的数据包(1024)。该设备可以连续流式传输数据一段时间,但也可以在任何时间长时间停止。如何处理这种行为?
当IsDataAvailable()返回false时,存在的主要问题是“热循环”。坦率地说,你*不需要检查* - 只是'读' – 2014-10-03 10:40:50
谢谢。我会考虑它。如果它不“破坏”我的算法并创建一个较小的CPU负载:) – Mackovich 2014-10-03 12:28:05