检查StreamReader是否有可用数据的非阻塞方法

Ale*_*pin 10 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.
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

如果我检查Peek()方法的单声道代码,它会在评论中说明

    //
    // Peek can block:
    // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=96484
    //
Run Code Online (Sandbox Code Playgroud)

不幸的是,该链接不再起作用.

我在这里,这里,这里这里发现微软似乎有一个导致Peek阻止的错误.但所有这些帖子都很老了.我认为mono故意Peek()因为这个bug 而阻塞.

所以我有两个问题

  1. 微软是否有导致Peek()阻止的错误?如果不是,mono应该将其实现更改Peek()为非阻塞.
  2. 有没有其他方法来检查StreamReader是否有数据可用而不阻塞线程?

ves*_*san 2

好吧,我只是说我真的不知道你想在这里完成什么。但是,据我所知,该Peek方法必须阻止当前线程才能工作。文档是这样说的:

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

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

您发布的链接中提到的问题与使用相同的多个线程有关StreamReader,这不是您的情况。我还相信,曾经有一个错误会导致一个StreamReader等待输入的人阻塞另一个人,但我相信它已经被修复了。我不确定 Mono 的实现是做什么的。

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

  1. 只需将整个事情放入一个单独的线程中即可。那么你就不会关心它是否被阻止了。
  2. 在任务上使用ReadAsyncand thenawaitContinueWith使其成为非阻塞的。

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