如果没有发送任何内容,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。

他建议三种方法来解决这个问题:

  1. 使用Socket.Shutdown()。这将返回ReadAsync,套接字错误为OperationAborted。
  2. 等待读取超时。
  3. 在从插座读取数据之前检查数据是否可用。

我通过在读取套接字之前检查数据是否可用来选择第三个选项。

我的最终代码:

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不会返回任何内容的主要内容,如果未能解决你的问题,请参考以下文章

返回响应时,Symfony 4.4 转储不输出任何内容

Sinatra Route什么都不返回

Facebook 权限不会弹出

量角器 sendKeys 不会向文本框发送任何内容

将表单名称发送到 JS/jQuery 和序列化

AkkaAkka 传递消息