有没有办法异步访问XmlReader?xml从许多不同的客户端(例如XMPP)进入网络; 它是<action>...</action>标签的恒定流.
我所追求的是能够使用类似BeginRead/EndRead的界面.我设法提出的最佳解决方案是在底层网络流上对0字节进行异步读取,然后当一些数据到达时,在XmlReader上调用Read-但是这将阻塞直到节点的所有数据变得可用了.该解决方案看起来大致如此
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);
}
Run Code Online (Sandbox Code Playgroud)
编辑:如果一个字符串包含一个完整的xml节点,这是一个可能的算法?
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;
};
Run Code Online (Sandbox Code Playgroud)
XmlReader 以 4kB 块的形式进行缓冲,如果我还记得几年前我研究这个问题的话。您可以将入站数据填充到 4kB(恶心!),或者使用更好的解析器。我通过将 James Clark 的 XP (Java) 移植到 C# 作为 Jabber-Net 的一部分来修复此问题,如下所示:
http://code.google.com/p/jabber-net/source/browse/#svn/trunk/xpnet
它是 LGPL,仅处理 UTF8,未打包使用,并且几乎没有文档,因此我不建议使用它。:)
| 归档时间: |
|
| 查看次数: |
5848 次 |
| 最近记录: |