Consider ASP.NET Core's ResponseBufferingMiddleware:
public class ResponseBufferingMiddleware
{
private readonly RequestDelegate _next;
public ResponseBufferingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var originalResponseBody = httpContext.Response.Body;
// no-op if buffering is already available.
if (originalResponseBody.CanSeek)
{
await _next(httpContext);
return;
}
var originalBufferingFeature = httpContext.Features.Get<IHttpBufferingFeature>();
var originalSendFileFeature = httpContext.Features.Get<IHttpSendFileFeature>();
try
{
// Shim the response stream
var bufferStream = new BufferingWriteStream(originalResponseBody);
httpContext.Response.Body = bufferStream;
httpContext.Features.Set<IHttpBufferingFeature>(new HttpBufferingFeature(bufferStream, originalBufferingFeature));
if (originalSendFileFeature != null)
{
httpContext.Features.Set<IHttpSendFileFeature>(new SendFileFeatureWrapper(originalSendFileFeature, bufferStream));
}
await _next(httpContext);
// If we're still buffered, set the content-length header and flush the buffer.
// Only if the content-length header is not already set, and some content was buffered.
if (!httpContext.Response.HasStarted && bufferStream.CanSeek && bufferStream.Length > 0)
{
if (!httpContext.Response.ContentLength.HasValue)
{
httpContext.Response.ContentLength = bufferStream.Length;
}
await bufferStream.FlushAsync();
}
}
finally
{
// undo everything
httpContext.Features.Set(originalBufferingFeature);
httpContext.Features.Set(originalSendFileFeature);
httpContext.Response.Body = originalResponseBody;
}
}
}
Link to actual file: https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/ResponseBufferingMiddleware.cs
Why is this not a memory leak? They create a new BufferingWriteStream (https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs), but never dispose of it. Does the HTTP Pipeline automatically dispose of streams after a finished request or something?
This stream is just a wrapper around other stream you pass in its constructor (originalResponseBody in this case). As such - there is no need to dispose it - by itself it does not contain any unmanaged resources it can clear\release, nor does it contain any other disposable components it should dispose, so there is no reason for it to implement IDisposable, but it inherits from class that already implements it. It just proxies all Stream methods (like Read and so on) to the wrapped stream with some additional logic (buffering).
As the title says.
Also, the other way around; will closing a RegistryKey dispose it?
I've looked around in all documentation I could find and nothing of this is mentioned anywhere.
It will call the Dispose() method inside of Close(), meaning YES it will be "disposed" and other way around Dispose() will Close() key. System registry keys are never closed. Only keys that are being closed - HKEY_PERFORMANCE_DATA.
.NET source for Close method:
/**
* Closes this key, flushes it to disk if the contents have been modified.
*/
public void Close() {
Dispose(true);
}
.NET source line 220
.NET source for Dispose method:
[System.Security.SecuritySafeCritical] // auto-generated
private void Dispose(bool disposing) {
if (hkey != null) {
if (!IsSystemKey()) {
try {
hkey.Dispose();
}
catch (IOException){
// we don't really care if the handle is invalid at this point
}
finally
{
hkey = null;
}
}
else if (disposing && IsPerfDataKey()) {
SafeRegistryHandle.RegCloseKey(RegistryKey.HKEY_PERFORMANCE_DATA);
}
}
}
.NET source line 227
I have a problem I cannot seem to figure out, please help. I have created a class to handle an interface to some HW using TcpClient. I want this class to send one last command to the HW before it is destroyed.
To solve this I have implemented IDisposable.Dispose to take care of the sending of the last command and then close the connection. I have also in the destructor made a call to Dispose. This is the Microsoft recommendation as I read it in this article. My code is as follows:
class MyHWInterface : IDisposable
{
~MyHWInterface()
{
Dispose();
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
CloseConnection();
disposed = true;
}
}
private System.Net.Sockets.TcpClient Port = new System.Net.Sockets.TcpClient();
public bool OpenConnection()
{
...
}
private bool SendCommand(string command)
{
var strm = Port.GetStream(); // This throws the exception Cannot access disposed object!
var w = new System.IO.StreamWriter(strm, System.Text.Encoding.ASCII);
var r = new System.IO.StreamReader(strm, System.Text.Encoding.ASCII);
w.WriteLine(command);
w.Flush();
string l = r.ReadLine();
return l == "OK";
}
internal void CloseConnection()
{
try
{
SendCommand("power down now");
}
catch
{
}
finally
{
Port.Close();
}
}
}
My problem is: When my program ends, and my object of MyHWInterface therefore falls out of scope and then gets garbage collected. The destructor is called which tries to send the last command, which fails because somehow my TcpClient is already disposed.
Please tell me why an object which is clearly not yet out of scope is being disposed. And please help with a method that makes sure my last command always will be send without an explicit call to Dispose.
Please tell me why an object which is clearly not yet out of scope is being disposed.
Objects don't have a concept of "scope" as such. At the end of your program, both the TcpClient and the instance of your class are eligible for finalization - and there's no guarantee which will be finalized first. It sounds like the TcpClient is being finalized (and the connection closed) first, hence the issue.
The best fix is not to rely on finalization for this in the first place - remove your own finalizer (realizing that the connection will just be closed at some point if the client doesn't call Dispose) and make sure that you do dispose of everything in an orderly fashion when your program terminates, assuming it's terminated cleanly (i.e. through some path you control).
I have some code to add attachments to an email. I'm adding them via the Stream overload of the Attachment class constructor. The code to do it looks like this:
List<UploadedDocument> docs = DataBroker.GetUploadedDocs(Convert.ToInt32(HttpContext.Current.Session["offer_id"].ToString()));
//no need to keep this in session
HttpContext.Current.Session["offer_id"] = null;
int counter = 1;
foreach (UploadedDocument doc in docs)
{
stream = new MemoryStream(doc.doc);
attach = new Attachment(stream, "Attachment-" + counter.ToString());
message.Attachments.Add(attach);
}
Where doc.doc is a byte array. I want to properly dispose of each attachment and stream, but I can't do it until the message has been sent, so I was thinking about just adding them to a List<Attachment> and List<Stream> and then iterating through and calling dispose.
Something like this:
List<Attachment> attachments;
List<Stream> streams;
//...
foreach(UploadedDocument doc in docs)
{
stream = new MemoryStream(doc.doc);
streams.Add(stream);
attach = new Attachment(stream,"Name");
attachments.Add(attach);
message.Attachments.Add(attach);
}
//other processing
emailClient.Send(message);
if(attachments != null)
{
foreach(Attachment attachment in attachments)
{
attachment.Dispose();
}
}
if(streams != null)
{
foreach(MemoryStream myStream in streams)
{
myStream.Dispose();
}
}
But something tells me that won't dispose them properly if there is still a reference floating around that hasn't gotten garbage collected or something. Any thoughts?
The simplest way to handle this is to just call Dispose() on the MailMessage.
MailMessage.Dispose will automatically dispose all attachments, which in turn will close/Dispose() all of the underlying streams.
//other processing
emailClient.Send(message);
message.Dispose(); // Or just wrap this entire block in a using statement
This is already implemented by MailMessage.Dispose method:
protected virtual void Dispose(bool disposing)
{
if (disposing && !this.disposed)
{
this.disposed = true;
if (this.views != null)
{
this.views.Dispose();
}
if (this.attachments != null)
{
this.attachments.Dispose();
}
if (this.bodyView != null)
{
this.bodyView.Dispose();
}
}
}
Just wrap usage of MailMessage into using statement and all resources, used by the MailMessage will be released after you leave using block:
using(var message = new MailMessage(from, to))
{
foreach (UploadedDocument doc in docs)
{
stream = new MemoryStream(doc.doc);
attach = new Attachment(stream, "Attachment-" + counter.ToString());
message.Attachments.Add(attach);
}
emailClient.Send(message);
}
There are already replies on right way (MailMessage.Dispose), so on "dispose them properly if there is still a reference...":
Dispose will (expected too) release resources at the moment of the call irrespective of who have references to the object. One of common approaches is to also have inner flag in the object that implements Dispose that will block any further calls by throwing "Object Disposed" exception.
You can (and probably already did) observe this behavior if you Dispose your streams before done using them. I.e. in your mail case you may try to dispose stream immediately after message.Attachments.Add(attach); which most likely will lead to "stream disposed" exception later during Send call.
Note that there are some objects like MemoryStream that have specially defined behavior after Dispose. I.e. MemoryStream blocks all calls except ToArray/Lenght/GetBuffer since one of the main purposes of this class is to give you resulting byte array of a stream. As side effect MemoryStream's Dispose is essentially only setting flag to block other calls (which is fine as this class does not have any native resources).
Classes such as Stream, StreamReader, StreamWriter etc implements IDisposable interface. That means, we can call Dispose() method on objects of these classes. They've also defined a public method called Close(). Now that confuses me, as to what should I call once I'm done with objects? What if I call both?
My current code is this:
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
using (StreamWriter writer = new StreamWriter(filename))
{
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
writer.Close();
}
reader.Close();
}
}
As you see, I've written using() constructs, which automatically call Dispose() method on each object. But I also call Close() methods. Is it right?
Please suggest me the best practices when using stream objects. :-)
MSDN example doesn't use using() constructs, and call Close() method:
How to: Download Files with FTP
Is it good?
A quick jump into Reflector.NET shows that the Close() method on StreamWriter is:
public override void Close()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
And StreamReader is:
public override void Close()
{
this.Dispose(true);
}
The Dispose(bool disposing) override in StreamReader is:
protected override void Dispose(bool disposing)
{
try
{
if ((this.Closable && disposing) && (this.stream != null))
{
this.stream.Close();
}
}
finally
{
if (this.Closable && (this.stream != null))
{
this.stream = null;
/* deleted for brevity */
base.Dispose(disposing);
}
}
}
The StreamWriter method is similar.
So, reading the code it is clear that that you can call Close() & Dispose() on streams as often as you like and in any order. It won't change the behaviour in any way.
So it comes down to whether or not it is more readable to use Dispose(), Close() and/or using ( ... ) { ... }.
My personal preference is that using ( ... ) { ... } should always be used when possible as it helps you to "not run with scissors".
But, while this helps correctness, it does reduce readability. In C# we already have plethora of closing curly braces so how do we know which one actually performs the close on the stream?
So I think it is best to do this:
using (var stream = ...)
{
/* code */
stream.Close();
}
It doesn't affect the behaviour of the code, but it does aid readability.
No, you shouldn't call those methods manually. At the end of the using block the Dispose() method is automatically called which will take care to free unmanaged resources (at least for standard .NET BCL classes such as streams, readers/writers, ...). So you could also write your code like this:
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
using (StreamWriter writer = new StreamWriter(filename))
{
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
}
The Close() method calls Dispose().
The documentation says that these two methods are equivalent:
StreamReader.Close: This implementation of Close calls the Dispose method passing a true value.
StreamWriter.Close:
This implementation of Close calls the Dispose method passing a true value.
Stream.Close: This method calls Dispose, specifying true to release all resources.
So, both of these are equally valid:
/* Option 1, implicitly calling Dispose */
using (StreamWriter writer = new StreamWriter(filename)) {
// do something
}
/* Option 2, explicitly calling Close */
StreamWriter writer = new StreamWriter(filename)
try {
// do something
}
finally {
writer.Close();
}
Personally, I would stick with the first option, since it contains less "noise".
For what it's worth, the source code for Stream.Close explains why there are two methods:
// Stream used to require that all cleanup logic went into Close(),
// which was thought up before we invented IDisposable. However, we
// need to follow the IDisposable pattern so that users can write
// sensible subclasses without needing to inspect all their base
// classes, and without worrying about version brittleness, from a
// base class switching to the Dispose pattern. We're moving
// Stream to the Dispose(bool) pattern - that's where all subclasses
// should put their cleanup now.
In short, Close is only there because it predates Dispose, and it can't be deleted for compatibility reasons.
This is an old question, but you can now(C# 8.0) write using statements without needing to block each one. They will be disposed of in reverse order when the containing block is finished.
using var responseStream = response.GetResponseStream();
using var reader = new StreamReader(responseStream);
using var writer = new StreamWriter(filename);
int chunkSize = 1024;
while (!reader.EndOfStream)
{
char[] buffer = new char[chunkSize];
int count = reader.Read(buffer, 0, chunkSize);
if (count != 0)
{
writer.Write(buffer, 0, count);
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/using
On many classes which support both Close() and Dispose() methods, the two calls would be equivalent. On some classes, however, it is possible to re-open an object which has been closed. Some such classes may keep some resources alive after a Close, in order to permit reopening; others may not keep any resources alive on Close(), but might set a flag on Dispose() to explicitly forbid re-opening.
The contract for IDisposable.Dispose explicitly requires that calling it on an object which will never be used again will be at worst harmless, so I would recommend calling either IDisposable.Dispose or a method called Dispose() on every IDisposable object, whether or not one also calls Close().
Just to complement other answers, as of C# 8.0, you don't need to open a block of code just to use an using statement
if (...)
{
using FileStream f = new FileStream(#"C:\users\jaredpar\using.md");
// statements
}
// Equivalent to
if (...)
{
using (FileStream f = new FileStream(#"C:\users\jaredpar\using.md"))
{
// statements
}
}
docs:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/using