Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查StreamReader是否有可用数据的非阻塞方式_C#_Mono - Fatal编程技术网

C# 检查StreamReader是否有可用数据的非阻塞方式

C# 检查StreamReader是否有可用数据的非阻塞方式,c#,mono,C#,Mono,我有一个StreamReader,我想知道在不阻塞线程的情况下是否有可用的数据 我尝试了Peek方法,但当没有可用数据时,它会阻塞 using (StreamReader reader = new StreamReader(stream)) { if (reader.Peek() == -1) // Blocks here while there is no data and unblocks as soon as there is data. { } } 如果我查一

我有一个
StreamReader
,我想知道在不阻塞线程的情况下是否有可用的数据

我尝试了
Peek
方法,但当没有可用数据时,它会阻塞

using (StreamReader reader = new StreamReader(stream))
{
    if (reader.Peek() == -1) // Blocks here while there is no data and unblocks as soon as there is data.
    {

    }
}
如果我查一下,它会在评论中说

    //
    // Peek can block:
    // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=96484
    //
不幸的是,这个链接不再起作用了

我发现,微软似乎有一个导致
Peek
阻塞的bug。但所有这些帖子都很老了。我想mono是因为这个bug故意阻塞了
Peek()

所以我有两个问题

  • Microsoft是否仍然存在导致
    Peek()
    被阻止的错误?如果否,mono应该将其
    Peek()
    的实现更改为非阻塞
  • 有没有其他方法可以在不阻塞线程的情况下检查StreamReader是否有可用的数据
  • 我不能给任何答案,我没有任何具体的情况下复制和测试,显然,来源是不可用的
  • 在.NET 4.5中,您可以使用StreamReader类中的ReadAsync方法

  • 好吧,让我说我真的不知道你在这里想要完成什么。但是,从我看到的情况来看,
    Peek
    方法必须阻塞当前线程才能工作。这就是文件中所说的:

    Peek方法返回一个整数值,以确定 文件结尾,或发生其他错误。这允许用户 在将返回值强制转换为字符之前,首先检查返回值是否为-1 类型

    因此,
    Peek
    只有在遇到错误或文件结尾时才应返回-1。这有点混乱,因为可能没有涉及任何文件。流可能是来自
    WebRequest
    的响应,在这种情况下,您尝试读取的流部分可能尚未下载。因此,
    Peek
    必须等待它完成,因为它返回从流中读取的第一个字节,这在文档中并不清楚

    您发布的链接中提到的问题与使用相同的
    StreamReader
    的多个线程有关,这与您的情况不同。我还相信,以前有一个bug会导致一个
    StreamReader
    等待输入来阻止另一个,但我相信它已经被修复了。我不确定Mono实现的功能

    要回答您的问题,在不阻塞线程的情况下执行此操作,我将尝试以下操作:

  • 把整件事放到另一条线里。那么你就不会在乎它是否被阻塞了
  • 在任务上使用
    ReadAsync
    ,然后使用
    wait
    ContinueWith
    ,使其非阻塞

  • 然而,正如评论中正确指出的那样,如果你把整个事情放到另一个线程中,你真的需要
    Peek
    ?为什么不将它放入典型的
    while(Read(…){…}
    块中,并在数据到来时对其进行处理?

    ReadAsync不会阻止线程,但不会告诉我是否有可用的数据。我需要知道流是否有可用数据。您可以始终读取一个小数据块的异步数据,并查看读取的字节数是否大于0。这种方式的使用就像一个窥视,除了你会消耗前几个字节实际上源是@Louis即使我读取异步一个字节并等待任务完成,它也会被阻止,直到接收到这一个字节我想很多人似乎忽略了的是不读取数据,到达河流的尽头是两件不同的事情。直到到达流的末尾,读取才会返回。它不会告诉您数据是否可用。它告诉您流是否有效或是否已到达末尾。例如,如果您正在从管道中读取数据,或者说是stdin或stderror。在该管道上收到足够的字节以满足请求之前,读取将不会完成。或者,如果管道已关闭,则它将返回已达到eof。您可以检查
    BaseStream
    是否为空。@juharr BaseStream不为空。我不明白你的意思,请解释清楚。为什么你关心“数据是否可用”?在我所看到的几乎每一个例子中,当有人认为他们想知道数据是否可用时,他们实际上并不想知道。他们只是认为这是解决不同问题的正确方法,而事实并非如此。对于I/O,几乎总是这样,您真正想要做的是尝试读取尽可能多的数据,并异步执行,以便在执行I/O时不会导致程序的其他部分暂停。您不需要Peek()我想这确实不是实现我想要的方法。@AlexandrePepin:如果
    BaseStream
    NetworkStream
    ,那么你可以使用
    NetworkStream.DataAvailable