NullReferenceException when sending XMLWrite output to httpContext.Response.OutputStream
-
08-07-2019 - |
Question
I have an application where every now and then I'm getting a strange error. This is the piece of code:
Dim XMLWriter As New System.Xml.XmlTextWriter(Me.Context.Response.OutputStream, Encoding.UTF8)
XMLWriter.WriteStartDocument()
XMLWriter.WriteStartElement("Status")
Message.SerializeToXML(XMLWriter)
XMLWriter.WriteEndElement()
XMLWriter.WriteEndDocument()
XMLWriter.Flush()
XMLWriter.Close()
The error i'm getting is: Message: Object reference not set to an instance of an object.
on line XMLWriter.Flush();
To make things more fun, this is absolutely non-reproducible. It just happens every now and then....
Since it's happening when flushing the XML i'm guessing the Object that is now null has to be the Response.OutputStream.
This is the relevant part of the stack trace:
Description:
An unhandled exception occurred and the process was terminated.
Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.
StackTrace: at System.Web.HttpWriter.BufferData(Byte[] data, Int32 offset, Int32 size, Boolean needToCopyData)
at System.Web.HttpWriter.WriteFromStream(Byte[] data, Int32 offset, Int32 size)
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.Xml.XmlTextWriter.Flush()
at RequestData.CompleteRequest(MessageBase Message) in RequestData.vb:line 142
My question is, in what cases could this be happening? This server is a long-polling server, so the client asks for something, and I may not answer for 30 seconds... Is it possible that this Stream will become Null if the client disconnects (ie. closes the browser window)?
Any other ideas? (any pointers appreciated)
Solution
Reflector gives this:
private void BufferData(byte[] data, int offset, int size, bool needToCopyData)
{
int num;
if (this._lastBuffer != null)
{
num = this._lastBuffer.Append(data, offset, size);
size -= num;
offset += num;
}
else if ((!needToCopyData && (offset == 0)) && !this._responseBufferingOn)
{
this._buffers.Add(new HttpResponseBufferElement(data, size));
return;
}
while (size > 0)
{
this._lastBuffer = this.CreateNewMemoryBufferElement();
this._buffers.Add(this._lastBuffer);
num = this._lastBuffer.Append(data, offset, size);
offset += num;
size -= num;
}
}
The only object that is not null checked, initialized or referenced through another method(which would show in the stack trace) is this._buffers. The only place it is set to null in that class is in RecycleBufferElements() which if you dig deeper can occur when the client disconnects.
OTHER TIPS
The call to Flush is what will cause anything cached in memory to be written out to the stream and ultimately the client so yes, it may be the problem.
You mentioned that the request is expected to take a long time to execute so it may be possible that ASP.Net or IIS are timing you out too early. I would suggest having a look at the executionTimeout property in the web.config and similar settings.
No, if it happens when you call Flush, that's way later than the only time Context.Response.OutputStream
is actually referenced. The value is fetched in the call to the XmlTextWriter
constructor, and then not looked at again.
Do you have any more information from the stack trace?