471,089 Members | 1,098 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,089 software developers and data experts.

XmlTextReader and NetworkStream blocking

Hi.

We have a Jabber-esque client server package that uses XMPP for
communication over network sockets.

Using .NET 2.0, I need to read a full stanza (i.e. balanced xml) as
soon as available and return it as a string.

So, I've taken my NetworkStream and wrapped an XmlTextReader around it.
At first I tried using ReadOuterXml() to grab the full stanza. This
worked fine except that it blocks until there is more data in the
stream behind the full stanza (since the ReadOuterXml() positions the
stream curser on the next element after the end element of the stanza).
This meant that the last message in would sit there until a new one
arrived...and this is not useful behaviour.

After some experimenting, I found that if I did a Read() on the start
element and then a ReadSubtree(), I could then do a ReadOuterXml() on
the subtrees reader and it returned the full stanza. The Read() blocks
until there is a new message, and the ReadSubtree() blocks until there
is a full stanza available.

However, the problem I've run into is that the ReadOuterXml() on the
subtree will block too, very occasionally (maybe .01% of the time, but
anything greater than 0% is unusable).

Is there a bug in ReadOuterXml()? Is there any other way (short of
writing my own parser) to grab full stanzas as strings?

Here is some sample code (C#) :

MyClass() {
static void Main(string[] args) {
TcpClient client = new TcpClient("hostname", port_no);
NetworkStream stream = client.GetStream();
StreamReader sIn = new StreamReader(stream, new
System.Text.UTF8Enconding(false));
XmlTextReader xIn = new XmlTextReader(sIn);

while (true) {
String stanza = xIn.ReadOuterXml(); // this blocks till
data following stanza
}
}
}
or then replace the "while" block in the above with this

xIn.Read();
while (true) {
if (xIn.IsStartElement()) {
XmlReader inner = xIn.ReadSubtree();
inner.Read();
String stanza = inner.ReadOuterXml(); // this
sometimes (< .01%) blocks
inner.Close();
xIn.Read();
} else
xIn.Read();
}
Does anyone have any insights?

Thanks,
Greg

Feb 22 '06 #1
3 4339
Hello Greg,

I don't see anything wrong with your code nor I am aware of any bug in
XmlTextReader or ReadOuterXml that could be causing the <.01% blocking.
Could it be because of some network issues?

Thanks,
-Helena Kotas, MS

<g6*******@hotmail.com> wrote in message
news:11*********************@o13g2000cwo.googlegro ups.com...
Hi.

We have a Jabber-esque client server package that uses XMPP for
communication over network sockets.

Using .NET 2.0, I need to read a full stanza (i.e. balanced xml) as
soon as available and return it as a string.

So, I've taken my NetworkStream and wrapped an XmlTextReader around it.
At first I tried using ReadOuterXml() to grab the full stanza. This
worked fine except that it blocks until there is more data in the
stream behind the full stanza (since the ReadOuterXml() positions the
stream curser on the next element after the end element of the stanza).
This meant that the last message in would sit there until a new one
arrived...and this is not useful behaviour.

After some experimenting, I found that if I did a Read() on the start
element and then a ReadSubtree(), I could then do a ReadOuterXml() on
the subtrees reader and it returned the full stanza. The Read() blocks
until there is a new message, and the ReadSubtree() blocks until there
is a full stanza available.

However, the problem I've run into is that the ReadOuterXml() on the
subtree will block too, very occasionally (maybe .01% of the time, but
anything greater than 0% is unusable).

Is there a bug in ReadOuterXml()? Is there any other way (short of
writing my own parser) to grab full stanzas as strings?

Here is some sample code (C#) :

MyClass() {
static void Main(string[] args) {
TcpClient client = new TcpClient("hostname", port_no);
NetworkStream stream = client.GetStream();
StreamReader sIn = new StreamReader(stream, new
System.Text.UTF8Enconding(false));
XmlTextReader xIn = new XmlTextReader(sIn);

while (true) {
String stanza = xIn.ReadOuterXml(); // this blocks till
data following stanza
}
}
}
or then replace the "while" block in the above with this

xIn.Read();
while (true) {
if (xIn.IsStartElement()) {
XmlReader inner = xIn.ReadSubtree();
inner.Read();
String stanza = inner.ReadOuterXml(); // this
sometimes (< .01%) blocks
inner.Close();
xIn.Read();
} else
xIn.Read();
}
Does anyone have any insights?

Thanks,
Greg

Feb 23 '06 #2
Hi Helena,

Thank you for your response.

Interestingly enough, I was able to get the problem to disappear (by
fluke really). Here's what changed.

Before, the code in the 2nd block (that uses the subtree) was actually
running in its own thread. So the main thread did all the socket
connection and stuff and then spawned a thread that did the reading of
the stream.

Now, I've added one level of threading. So, the main thread spawns a
thread that does all the connection stuff and that spawned thread
spawns another to do the reading. Other than that, the code is
unchanged. But now I do not see the <.01% blocking anymore.

Of course...this makes me a little nervous since it should not have
made any difference.

Any thoughts on why this change would stop the problem from happening?

Thanks,
Greg

Feb 23 '06 #3
Hi Greg,

not sure if your problem is related to the following. WIth .NET 1.1 SP1
Microsoft made changes in the XMLTextReader. So with 1.1 SP1 you are
not able to read networkstreams correctly. Here is a big thread about
the problem:
http://mail.jabber.org/pipermail/jab...hread.html#342
Would be interesting to know if this is fixed this is 2.0, or if there
is the same problem.

Alex

Feb 26 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Stelrad Doulton | last post: by
2 posts views Thread by PiotrKolodziej | last post: by
4 posts views Thread by Cyron | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.