我正试图通过Xamarin.Android中的蓝牙接收数据。如果我有数据要接收,我的方法工作正常。但是如果没有发送任何内容,则从Stream.Read方法(_inputStream.Read(buffer, 0, buffer.Length)
)返回任何内容。
知道我做错了什么吗?
private Stream _inputStream;
public string ReceiveData()
{
byte[] buffer = new byte[30];
try
{
while (true)
{
int read = _inputStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
return null;
}
char[] result = Encoding.ASCII.GetChars(buffer);
if (!result[0].Equals("\0"))
{
return result[0].ToString();
}
}
}
catch (Exception)
{
// Não implementado
}
return null;
}
问题在于_inputStream.Read(buffer, 0, buffer.Length)
。如果没有通过蓝牙发送任何内容,我会陷入其中。没有返回任何内容,也没有异常。
编辑1
正如@rene建议的那样,我尝试使用带有1500毫秒的CancellationToken的Task / Async。我得到了同样的行为。
public async Task<string> ReceiveData()
{
byte[] buffer = new byte[30];
CancellationTokenSource token = new CancellationTokenSource();
token.CancelAfter(TimeSpan.FromMilliseconds(1500));
try
{
while (true)
{
int read = await _inputStream.ReadAsync(buffer, 0, buffer.Length, token.Token);
if (read <= 0)
{
return null;
}
char[] result = Encoding.ASCII.GetChars(buffer);
if (!result[0].Equals("\0"))
{
return result[0].ToString();
}
}
}
catch (Exception ex)
{
// Não implementado
}
return null;
}
正如James Harmon在Cancel ReadAsync中所说,由于内部调用是不受管理的并且使用IOCompletion端口,因此无法取消Stream.ReadAsync。
他建议三种方法来解决这个问题:
我通过在读取套接字之前检查数据是否可用来选择第三个选项。
我的最终代码:
public async Task<string> ReceiveData()
{
byte[] buffer = new byte[30];
try
{
while (true)
{
if(_inputStream.IsDataAvailable())
{
int read = await _inputStream.ReadAsync(buffer, 0, buffer.Length);
if (read <= 0)
{
return null;
}
char[] result = Encoding.ASCII.GetChars(buffer);
if (!result[0].Equals("\0"))
{
return result[0].ToString();
}
}
}
}
catch (Exception)
{
// Não implementado
}
return null;
}
非常感谢H.G. Sandhagen。