【发布时间】:2014-10-03 10:29:20
【问题描述】:
由于我的问题与这个问题很接近,我一直在寻找这个可能的解决方案的反馈:Reading on a NetworkStream = 100% CPU usage 但我找不到我需要的解决方案。
就像在这个其他问题中一样,我想使用除无限 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
按照 Marc 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)
}
你怎么称呼这段代码 sn-p ? 两个问题:
如果没有可读取的内容,则 while 条件将为 被解雇:下一步该做什么?
读完之后,接下来要做什么?您如何捕获任何新的传入数据包?
以下是一些应该有所帮助的解释:
- android 设备通过蓝牙连接到另一个发送数据的设备。它将始终发送具有指定大小 (1024) 的预先设计的数据包
- 该设备可以在一段时间内连续流式传输数据,但也可以在很长一段时间内随时停止。如何处理此类行为?
【问题讨论】:
-
当
IsDataAvailable()返回false时,主要问题似乎是“热循环”。坦率地说,您不需要检查 - 只需Read -
谢谢。我会考虑的。如果它没有“破坏”我的算法并创建更小的 CPU 负载:)
标签: android .net bluetooth stream xamarin