繁体   English   中英

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

[英]C# WebClient StreamReader continuous read missing last line

问候好人,

关于 WebClient 和读取连续数据流的数据,我有一个相当奇怪的问题(至少对我来说),我不确定问题出在哪里。 该流几乎按预期接收数据,除了最后一行。 但是当新数据到达时,未打印的行会打印在新数据的上方。

例如,一组行被检索,它可能看起来像这样:

<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 永远不会变为 true,因为流没有结束。 有人对如何检索最后一行有建议吗? 我是否遗漏了什么,或者 API 可能有问题?

亲切的问候 :)

batch元素之后似乎根本没有换行符。 在 XML 中,包括换行符在内的空格并不重要,因此不需要换行符。 但是 XML 不允许多个根元素,这使得这种情况有点奇怪。

在流式传输场景中,通常不缩进发送每条消息(即在单行中)并发送换行符或另一个不常见的字符来标记消息的结尾。 人们会期望根本没有换行符,或者在每批之后都有一个换行符,例如:

<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);
    ...
}

但是,如果没有其他方法来识别每条消息,您将不得不从流中读取每个元素。 幸运的是, LINQ-to-XML使得阅读元素更容易一些:

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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM