문자열을 XElement로 파싱하여 이상한 동작을 관찰했습니다. 이제 코드XElement를 파싱하는 동안 이상한 동작이 발생했습니다.
<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);
}
먼저, 여기에 내가 구문 분석 할 XML이다.
때때로 try 블록이 XmlException ("루트 요소가 없습니다.")을 발생 시키지만 catch 블록 (정확히 똑같은 일을하는)은 throw하고 문자열을 올바르게 구문 분석하지 않습니다.
누군가 내게 이유를 말해 줄 수 있습니까?
감사합니다.
[편집] 여기
전체 방법 코드 :
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이 채워지지 않았다는 것이 매우 이상한 것 같습니다 ... –
@Arnaud :'_responseBytes'는 어디에 쓰여 집니까? 'buffer' 란 무엇입니까?우리가 아직 가지고 있지 않은 많은 코드가 있습니다. 질문을 짧지 만 완성 된 프로그램으로 편집 할 수 있다면 훨씬 더 쉽게 도움이 될 것입니다. –
재미있는 점에 대해 감사합니다. 편집을 참조하십시오. _responseBytes가 작성되는 코드를 추가했습니다. –