如果没有发送任何内容,Stream.Read不会返回任何内容
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果没有发送任何内容,Stream.Read不会返回任何内容相关的知识,希望对你有一定的参考价值。
我正试图通过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(" "))
{
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(" "))
{
return result[0].ToString();
}
}
}
catch (Exception ex)
{
// Não implementado
}
return null;
}
答案
正如James Harmon在Cancel ReadAsync中所说,由于内部调用是不受管理的并且使用IOCompletion端口,因此无法取消Stream.ReadAsync。
他建议三种方法来解决这个问题:
- 使用Socket.Shutdown()。这将返回ReadAsync,套接字错误为OperationAborted。
- 等待读取超时。
- 在从插座读取数据之前检查数据是否可用。
我通过在读取套接字之前检查数据是否可用来选择第三个选项。
我的最终代码:
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(" "))
{
return result[0].ToString();
}
}
}
}
catch (Exception)
{
// Não implementado
}
return null;
}
非常感谢H.G. Sandhagen。
以上是关于如果没有发送任何内容,Stream.Read不会返回任何内容的主要内容,如果未能解决你的问题,请参考以下文章