C#WebClient StreamReader连续阅读缺少最后一行

发布于 2025-02-03 21:47:46 字数 825 浏览 2 评论 0原文

问候好人,

关于网络电视机和读取连续数据流的数据,我有一个相当奇怪的问题,我不确定问题在哪里。该流几乎按预期接收数据,除了最后一行。但是,当新数据到达时,未打印的行将在新数据上方打印。

例如,一组线被重新编排,并且看起来像这样:

<batch name="home">
    <event id="1"/>

当下一组到达时,它包含上面集合中缺少的端块:

</batch>
<batch name="home">
    <event id="2"/>

简化了所示的代码,但希望足以获得更清晰的图片。

WebClient _client = new WebClient();

_client.OpenReadCompleted += (sender, args) =>
{
    using (var reader = new StreamReader(args.Result))
    {
        while (!reader.EndOfStream)
        {
            Console.WriteLine(reader.ReadLine());
        }
    }
};

_client.OpenReadAsync(new Uri("localhost:1234/testdata?keep=true"));

在此设置中,Reader.endofstream永远不会实现,因为该流没有结束。 有人对如何检索最后一行有建议吗?我是否缺少某些内容,或者API的错?

亲切的问候 :)

Greetings good people,

I have a rather strange issue (for me at least) regarding WebClient and reading data for a continuous data stream and I’m not really sure where the issue is. The stream receives data almost as expected, except the last row. But when new data arrives, the unprinted row prints above the new data.

For example, a set of lines is retreived and it could look like this:

<batch name="home">
    <event id="1"/>

And when the next set arrives, it contains the missing end block from the above set:

</batch>
<batch name="home">
    <event id="2"/>

The code presented is simplified, but hopefully is enough for getting a clearer picture.

WebClient _client = new WebClient();

_client.OpenReadCompleted += (sender, args) =>
{
    using (var reader = new StreamReader(args.Result))
    {
        while (!reader.EndOfStream)
        {
            Console.WriteLine(reader.ReadLine());
        }
    }
};

_client.OpenReadAsync(new Uri("localhost:1234/testdata?keep=true"));

In this setup the reader.EndOfStream never gets to true because the stream doesn't end.
Anyone have a suggestion on how to retrieve the last line? Am I missing something or could the fault be with the API?

Kind regards :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄荷港 2025-02-10 21:47:46

batch元素之后,似乎根本没有newline字符。在XML Whitespace中,包括Newlines,并不重要,因此不需要新线。 XML不允许多个根部元素,这使此情况有些怪异。

在流媒体方案中,通常发送每个消息(即单行)并发送newline或其他不常见字符以标记消息结束是很常见的。一个人会期望完全期望 no newlines,或者每批之后的新线,例如:

<batch name="home"><event id="1"/>...</batch>
<batch name="home"><event id="2"/>...</batch>
<batch name="home"><event id="3"/>...</batch>

在这种情况下,您可以使用readline读取每个消息:

var client=new HttpClient();
using var stream=client.GetStreamAsync(serviceUrl);

using var reader=new StreamReader(stream);
while(true)
{
    var msg=reader.ReadLine();
    var doc=XDocument.Parse(msg);
    ...
}

没有其他方法不过,确定每个消息,您必须读取每个元素形式的流。幸运的是,使阅读元素更容易:

using var reader=XmlReader.Create(stream,new XmlReaderSettings{ConformanceLevel = ConformanceLevel.Fragment});
while (reader.Read())
{
    switch (reader.NodeType)
    {
        case XmlNodeType.Element:
            if (reader.Name == "batch") {
                    XElement el = XElement.ReadFrom(reader) as XElement;
                    //Process the batch!
            }
            break;
    }
}

It seems there's simply no newline character after the batch element. In XML whitespace, including newlines, isn't significant so no newlines are required. XML doesn't allow multiple root elements though, which makes this scenario a bit weird.

In streaming scenarios it's common to send each message unindented (ie in a single line) and send either a newline or another uncommon character to mark the end of the message. One would expect either no newlines at all, or a newline after each batch, eg :

<batch name="home"><event id="1"/>...</batch>
<batch name="home"><event id="2"/>...</batch>
<batch name="home"><event id="3"/>...</batch>

In that case you could use just a ReadLine to read each message:

var client=new HttpClient();
using var stream=client.GetStreamAsync(serviceUrl);

using var reader=new StreamReader(stream);
while(true)
{
    var msg=reader.ReadLine();
    var doc=XDocument.Parse(msg);
    ...
}

Without another way to identify each message though, you'll have to read each element form the stream. Luckily, LINQ-to-XML makes it a bit easier to read elements :

using var reader=XmlReader.Create(stream,new XmlReaderSettings{ConformanceLevel = ConformanceLevel.Fragment});
while (reader.Read())
{
    switch (reader.NodeType)
    {
        case XmlNodeType.Element:
            if (reader.Name == "batch") {
                    XElement el = XElement.ReadFrom(reader) as XElement;
                    //Process the batch!
            }
            break;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文