1
我觀察到一個奇怪的行爲,通過解析字符串到XElement。C# - 解析XElement時的奇怪行爲
首先,這裏是我想要解析XML:
<return value="0">
<resultset>
<meta>
<column type="char(30)"></column>
</meta>
<datarow>
<datacol>
<![CDATA[master]]>
</datacol>
</datarow>
</resultset>
</return>
現在代碼:
try
{
xmlResult = XElement.Parse(
_UTF8Encoder.GetString(_responseBytes.GetBuffer(), 0, (int)_responseBytes.Length),
LoadOptions.PreserveWhitespace);
}
catch
{
xmlResult = XElement.Parse(
_UTF8Encoder.GetString(_responseBytes.GetBuffer(), 0, (int)_responseBytes.Length),
LoadOptions.PreserveWhitespace);
}
我做同樣的事情在try和catch塊。
有時候,try塊會引發XmlException(「Root元素丟失」),但catch塊(完全一樣的東西)不會拋出它並正確解析字符串。
有人能告訴我爲什麼嗎?
謝謝!
[編輯]
這裏是整個方法的代碼:
private TcpClient _client;
private NetworkStream _clientStream;
private MemoryStream _responseBytes;
private readonly UTF8Encoding _UTF8Encoder = new UTF8Encoding();
private const int BUFFER_SIZE = 1024;
private XElement Receive()
{
byte[] buffer = new byte[BUFFER_SIZE];
XElement xmlResult;
Encoding serverEncoding = this.Task.Server.Encoding;
// Reading result
while (true)
{
_responseBytes = new MemoryStream();
try
{
IAsyncResult e = _clientStream.BeginRead(buffer,
0, // Begin
BUFFER_SIZE, // Length
new AsyncCallback(OnBeginRead), // Callback used
new SocketAsyncState(_clientStream, buffer)); // Passing buffer to callback
e.AsyncWaitHandle.WaitOne(); // Wait until data are in pipe
if (((SocketAsyncState)e.AsyncState).HasError)
{
throw new ObjectDisposedException();
}
// Try to convert to a XElement, if fail, redo all process.
_responseBytes.Position = 0;
try
{
xmlResult = XElement.Parse(
_UTF8Encoder.GetString(_responseBytes.GetBuffer(), 0, (int)_responseBytes.Length),
LoadOptions.PreserveWhitespace);
}
catch
{
xmlResult = XElement.Parse(
_UTF8Encoder.GetString(_responseBytes.GetBuffer(), 0, (int)_responseBytes.Length),
LoadOptions.PreserveWhitespace);
}
// Result 100% retrieved : quit loop
break;
}
catch (Exception ex)
{
if (ex is ObjectDisposedException
|| ex is XmlException)
{
while (!IsConnected) { Wait(); } // Wait that the network comes back
SendSyn(); // Relaunch process
}
}
}
// Result 100% retrieved : send ACK to Socket
SendAck();
return xmlResult;
}
private void OnBeginRead(IAsyncResult ar)
{
SocketAsyncState state = ar.AsyncState as SocketAsyncState;
byte[] nextBuffer = new byte[BUFFER_SIZE];
int numberOfBytesReaded;
Encoding serverEncoding = this.Task.Server.Encoding;
try
{
numberOfBytesReaded = state.Stream.EndRead(ar);
}
catch(Exception)
{
((SocketAsyncState)ar.AsyncState).HasError = true;
// Quit
return;
}
// While data are available, read next buffer (recursive call to this method)
if (state.Stream.DataAvailable && state.Stream.CanRead)
{
state.Stream.BeginRead(nextBuffer,
0,
BUFFER_SIZE,
new AsyncCallback(OnBeginRead),
new SocketAsyncState(state.Stream, nextBuffer));
}
// Default C# strings are in UTF-8, so convert stream only if needed
if (serverEncoding.CodePage != _UTF8Encoder.CodePage)
{
byte[] buffer = Encoding.Convert(serverEncoding,
_UTF8Encoder,
state.Data.TakeWhile((b) => b != '\0').ToArray());
_responseBytes.Write(buffer, 0, buffer.Length);
}
else
{
_responseBytes.Write(state.Data, 0, numberOfBytesReaded);
}
}
請參閱編輯。你是對的,所有的都是異步完成的,但是似乎很奇怪MemoryStream沒有被填充...... – 2011-01-14 11:56:44