.NET 中的异步 XmlReader? [英] Asynchronous XmlReader in .NET?

查看:21
本文介绍了.NET 中的异步 XmlReader?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法异步访问 XmlReader?xml 来自许多不同的客户端,例如 XMPP;它是 ...> 标签的恒定流.

Is there a way to access a XmlReader asynchronously? The xml is coming in off the network from many different clients like in XMPP; it is a constant stream of <action>...</action> tags.

我所追求的是能够使用类似 BeginRead/EndRead 的界面.我设法想出的最佳解决方案是在底层网络流上对 0 字节进行异步读取,然后当一些数据到达时,在 XmlReader 上调用 Read——但是这将阻塞,直到来自节点的所有数据变得可用.该解决方案大致如下

What i'm after is to be able to use a BeginRead/EndRead-like interface. The best solution I've managed to come up with is to do an asynchronous read for 0 bytes on the underlying network stream, then when some data arrives, call Read on the XmlReader- this will however block until all of the data from the node becomes available. That solution looks roughly like this

private Stream syncstream;
private NetworkStream ns;
private XmlReader reader;

//this code runs first
public void Init()
{
    syncstream = Stream.Synchronized(ns);
    reader = XmlReader.Create(syncstream);
    byte[] x = new byte[1];
    syncstream.BeginRead(x, 0, 0, new AsynchronousCallback(ReadCallback), null);
}

private void ReadCallback(IAsyncResult ar)
{
    syncstream.EndRead(ar);
    reader.Read(); //this will block for a while, until the entire node is available
    //do soemthing to the xml node
    byte[] x = new byte[1];
    syncstream.BeginRead(x, 0, 0, new AsynchronousCallback(ReadCallback), null);
}

如果一个字符串包含一个完整的 xml 节点,这是一种可能的算法吗?

This is a possible algorithm for working out if a string contains a complete xml node?

Func<string, bool> nodeChecker = currentBuffer =>
                {
                    //if there is nothing, definetly no tag
                    if (currentBuffer == "") return false;
                    //if we have <![CDATA[ and not ]]>, hold on, else pass it on
                    if (currentBuffer.Contains("<![CDATA[") && !currentBuffer.Contains("]]>")) return false;
                    if (currentBuffer.Contains("<![CDATA[") && currentBuffer.Contains("]]>")) return true;
                    //these tag-related things will also catch <? ?> processing instructions
                    //if there is a < but no >, we still have an open tag
                    if (currentBuffer.Contains("<") && !currentBuffer.Contains(">")) return false;
                //if there is a <...>, we have a complete element.
                //>...< will never happen because we will pass it on to the parser when we get to >
                if (currentBuffer.Contains("<") && currentBuffer.Contains(">")) return true;
                //if there is no < >, we have a complete text node
                if (!currentBuffer.Contains("<") && !currentBuffer.Contains(">")) return true;
                //> and no < will never happen, we will pass it on to the parser when we get to >
                //by default, don't block
                return false;
            };

推荐答案

XmlReader 以 4kB 块的形式缓冲,如果我记得几年前我看到这个的时候.您可以将入站数据填充到 4kB(哎呀!),或者使用更好的解析器.我通过将 James Clark 的 XP(Java)移植到 C# 作为 Jabber-Net 的一部分来解决这个问题,这里:

XmlReader buffers in 4kB chunks, if I remember from when I looked in to this a couple of years ago. You could pad your inbound data to 4kB (ick!), or use a better parser. I fixed this by porting James Clark's XP (Java) to C# as a part of Jabber-Net, here:

http://code.google.com/p/jabber-net/source/browse/#svn/trunk/xpnet

它是 LGPL,只处理 UTF8,没有打包使用,而且几乎没有文档,所以我不建议使用它.:)

It's LGPL, only handles UTF8, isn't packaged for use, and has almost no documentation, so I wouldn't recommend using it. :)

这篇关于.NET 中的异步 XmlReader?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆