Native resource cleanup and Not calling Dispose - c#

Can anyone explain why not calling Dispose() explicitly, and native resource still gets cleaned up. Does it get called implicitly?
I came cross below
calling Dispose is not required to guarantee native resource cleanup.
Native resource cleanup will always happen eventually; calling
Dispose lets you control when that cleanup happens.
// Create the bytes to write to the temporary file.
Byte[] bytesToWrite = new Byte[] { 1, 2, 3, 4, 5 };
// Create the temporary file.
FileStream fs = new FileStream("Temp.dat", FileMode.Create);
// Write the bytes to the temporary file.
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
// Explicitly close the file when finished writing to it.
//fs.Dispose();
Dispose should be called explicitly in code within finally block or via using statement.

FileStream contains Finalize method which calls Dispose inside:
~FileStream()
{
if (_handle != null) {
BCLDebug.Correctness(_handle.IsClosed, "You didn't close a FileStream & it got finalized. Name: \""+_fileName+"\"");
Dispose(false);
}
}
Which means it will be eventually called by Finalizer when the object will not be longer reachable. Of course, it is good to call Dispose explictly as it let's you control cleanup deterministicaly as you've mentioned.

The garbageCollector is cleaning up unreferenced Objects, when it gets resources of the OS, but if you have a highly frequented Application it might be useful not to have to wait for it, because otherwise your memory gets filled up. Then the usage of Dispose is quite necessary.
Update:
The objects do not even need to implement IDisposable to be cleaned up, because it's the Finalize-Method that is called.

Related

Should I dispose FileUpload.PostedFile.InputStream?

Is this code needed, or because the UnLoad event of the page disposes all controls on page anyway there's no point in writing such code:
fu.PostedFile.InputStream.Flush();
fu.PostedFile.InputStream.Close();
fu.FileContent.Dispose();
I'm asking because on examples from msdn I see that they write code like
FileUpload1.SaveAs(savePath);
but don't ever bother to dispose the stream afterwards, but on the hand I see some people do explicitly dispose the input stream after saving?
Official guidance suggests that there is no need to dispose this stream, as it will be disposed when request processing ends:
Server resources that are allocated to buffer the uploaded file will be destroyed when the request ends. To save a durable copy of the file, use the SaveAs method.
To back this up I also did a bit of code digging through the sources. Turns out that neither FileUpload nor HttpPostedFile are responsible for disposing this stream. In fact they themselves do not hold any resources at all, and just provide an interface to access parts of the request.
HttpRequest does some disposal. But not all disposable objects are being disposed. Here is its Dispose:
/*
* Cleanup code
*/
internal void Dispose() {
if (_serverVariables != null)
_serverVariables.Dispose(); // disconnect from request
if (_rawContent != null)
_rawContent.Dispose(); // remove temp file with uploaded content
}
What is not disposed however is the collection HttpRequest.Files, which the upload controls interface. To fill this collection up with data every posted file is wrapped into an HttpPostedFile object, and an HttpInputStream is created for each. This stream object holds the reference to the whole data (see rawContent above) and knows about offset and length of relevant file part. It is worth noting that HttpInputStream implements IDisposable, however I wasn't able to find the code that disposes these stream objects.
To sum it up:
Upload controls do not dispose the stream
Request or HttpContext do not dispose the stream either
However Request disposes the underlying data
So it looks like the idea here is that when request processing is finished, references to the relevant data will be dropped and it will be disposed. So it won't hurt to manually dispose the stream you've used, but it is also not necessary.

Why do bitmaps stay in memory unless I call GC.Collect?

I'm developing an application that connects to a GigEVision camera, and pulls images from it. I'm currently using the Pleora eBus SDK with C#.NET.
The code below is just a test application for the camera connection - it can stream images, but rapidly runs out of memory unless I call GC.Collect();
It's worth noting the images being streamed are large (4096x3072), so the crash happens fairly quickly.
I suspected at first that not calling Dispose() was the issue. However, I can call Dispose() on each image right before getting rid of the reference to it, and that did not fix the issue.
I've also tried explicitly releasing the buffers that come into the display thread callback, but that had no effect.
Can I get my memory back in a more elegant way?
using System;
using System.Windows.Forms;
using PvDotNet;
using PvGUIDotNet;
using System.Drawing;
namespace eBus_Connection
{
public partial class MainForm : Form
{
PvDeviceGEV camera;
PvStreamGEV stream;
PvPipeline pipeline;
PvDisplayThread thread;
bool updating = false;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Shown(object sender, EventArgs e)
{
PvDeviceInfo info;
PvDeviceFinderForm form = new PvDeviceFinderForm();
form.ShowDialog();
info = form.Selected;
camera = PvDeviceGEV.CreateAndConnect(info) as PvDeviceGEV;
stream = PvStreamGEV.CreateAndOpen(info.ConnectionID) as PvStreamGEV;
pipeline = new PvPipeline(stream);
if (camera == null || stream == null)
throw new Exception("Camera or stream could not be created.");
camera.NegotiatePacketSize();
camera.SetStreamDestination(stream.LocalIPAddress, stream.LocalPort);
camera.StreamEnable();
camera.Parameters.ExecuteCommand("AcquisitionStart");
pipeline.Start();
thread = new PvDisplayThread();
thread.OnBufferDisplay += thread_OnBufferDisplay;
thread.Start(pipeline, camera.Parameters);
status.DisplayThread = thread;
status.Stream = stream;
}
void thread_OnBufferDisplay(PvDisplayThread aDisplayThread, PvBuffer aBuffer)
{
Bitmap b = new Bitmap((int)aBuffer.Image.Width, (int)aBuffer.Image.Height);
aBuffer.Image.CopyToBitmap(b);
BeginInvoke(new Action<Bitmap>(ChangeImage), b);
}
void ChangeImage(Bitmap b)
{
if (PictureBox.Image != null)
PictureBox.Dispose();
PictureBox.Image = b;
GC.Collect();//taking this away causes memory to leak rapidly.
}
}
}
It's very likely that somewhere in your code an Image such as a Bitmap is not being disposed. Bitmap extends Image which implements IDisposable which means you need to call Dispose() on it when you're done with it (often by wrapping it with a using statement). You aren't disposing the Bitmap or Image somewhere so the GC finalizes it when it can (or in this case when you explicitly invoke the GC).
Once the GC determines that a class is no longer referenced, it becomes available to clean up... Before cleaning it up, it checks for a finalizer. If a finalizer exists, the class is placed in a special GC finalizer queue that will run the finalizer before cleaning up the resources/memory. Most IDisposable classes have finalizers which allow the GC to do the Dispose() call work in case you forgot to manually dispose the class yourself. It seems that this is what is happening to your code, but without seeing ALL classes I can only guess what isn't disposed (and no idea where).
EDIT: I do have a guess though. I bet the PictureBox.Dispose() call does not dispose PictureBox.Image
If an object implements IDisposable then you should absolutely call Dispose on it but disposing an object doesn't release the memory it occupies. It releases things like, in this case, an image handle. Such resources have to be released first, before memory can be reclaimed, so disposing still helps.
When the GC runs, if an object hasn't been disposed then it must first finalise it, meaning that it must wait longer to reclaim the memory. If the object has been disposed, memory is reclaimed as soon as the GC runs.
The GC runs in the background though. If your application is busy allocating more and more memory then the GC never gets a chance to run and reclaim it, regardless of whether you dispose objects or not. In such cases, you need to invoke the GC explicitly from time to time. Creating multiple images is the most common scenario that requires explicit GC invocation.
It's worth noting that ALL objects remain in memory until the GC runs and cleans them up, whether the object implements IDisposable or not. You normally don't notice it though, because most apps have enough down-time to allow the GC to run implicitly and reclaim that memory. There's nothing special about your Bitmap objects in this regard.
You are disposing the picture box instead of the image. Even if that will dispose the image in the picture box, it will only do that the first time. After that the picture box is in a disposed state and calling Dispose again will do nothing.
You should get the image reference from the picture box and dispose it once it's not used any more:
void ChangeImage(Bitmap b) {
Image oldImage = PictureBox.Image;
PictureBox.Image = b;
if (oldImage != null) {
oldImage.Dispose();
}
}
A bitmap that isn't disposed correctly have to be finalized before it can be collected. There is a background thread that finalizes objects that needs to be collected, but if you abandon objects faster than that thread can take care of them, you will run out of memory.
When the bitmap is disposed correctly, it becomes a regular managed object that can be collected right away whenever the garbage collector wants to.

C# garbage collector seems to be closing my StreamWriter too early

I have a logger class thats a singleton. In it's destructor I call Close() which prints the footer for the log and then closes the StreamWriter.
public void Close()
{
WriteLogFileFooter();
_logFile.Flush();
_logFile.Close();
}
The problem is when System.Enviornment.Exit(1) is called from elsewhere in the program (portions that I didn't write myself), the footer is never printed and my logger throws an exception for trying to write to a closed stream. I can only assume the Exit command is causing my StreamWriter to be closed before my Singleton is destructed. I tried to use GC.SupressFinalize() on my StreamWriter but that didn't seem to help.
You are violating one explicit rule for finalizers:
The Finalize method should not reference any other objects.
http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=VS.90).aspx
It's entirely possible that the managed object you hold a reference to is collected before your object is collected when the application exits.
UPDATE
If you need to clean up managed resources when the application exits, you could hook up the ProcessExit event of AppDomain rather than rely on non-deterministic behavior of finalizer execution.
.NET Console Application Exit Event
You should make your logger implement IDisposable, and use it in a using block. This means that it will be deterministically disposed, whereas now it is being nondeterministically destructed.
The cause of the error is that your stream will sometimes be closed before the logger, as Exit basically destroys everything (nondeterministically) and quits. You should use a deterministic pattern (IDisposable) to avoid this.
In reality, destructors are rarely useful in C#, for the precise reason that they are non-deterministic. They only are worth using for releasing unmanaged resources.
Also, implementing IDisposable may make it inconvenient to use a singleton. I personally think it's better to create an instance to be used throughout the program and disposed at the end, rather than an explicit singleton.
As others have already clearly stated, you should not attempt to access your _logFile object at all from your logger class' finalizer. You shouldn't access any other objects in a finalizer, because the Garbage Collector might already have wiped them out of existence.
I think you could avoid your problem by a few simple steps:
Get rid of your current finalizer.
Perform a _logFile.Flush after every single write, instead of waiting until the very end of your logger object's lifetime when it might already be too late.
Flushing a log file stream frequently seems legitimate to me because the whole point of having a log is using it to find, and deal with, situations where errors have occurred. If your process is suddenly terminated by an exceptional situation, your log should still be as complete as possible; thus flushing the log stream buffer frequently seems a sensible thing to do.
Make your logger implement IDisposable (this MSDN Magazine article will explain to you how this is done) and close your log file stream from there.
I had the same problems and my solution was as follows:
When creating the FileStream in the constructor of your class used GC.SuppressFinalize immediately. This makes you responsible for cleaning the stream
Close the stream in the Dispose() of the class
public class LogFileEventListener : IDisposable
{
private bool disposed = false;
private FileStream fileStream;
public LogFileEventListener(string path)
{
//Opens a new file stream to log file
this.fileStream = new FileStream(path, FileMode.Append, FileAccess.Write);
GC.SuppressFinalize(this.fileStream);
}
/// <summary>Finalize the listener</summary>
~LogFileEventListener() { this.Dispose(); }
/// <summary>Disposes the listener</summary>
public override void Dispose()
{
try
{
if (!this.disposed)
{
/* Do you stuff */
//Close the log file
if (this.fileStream != null)
{
this.fileStream.Close();
this.fileStream = null;
}
base.Dispose();
}
}
finally
{
this.disposed = true;
GC.SuppressFinalize(this);
}
}
}
Most likely the StreamWriter is being closed else where.
Try creating an additional StreamWriter in your singleton's constructor, write to it a few times (to confirm that it is working), then write to it again in the destructor before calling close (close will also flush).
If the above works then you will know some other code is closing your log. If it does not work then you will know that it is a .NET thing (possibly having something to do with how/where the variable is referenced).
According to the documentation, you should be able to work around the issue by putting the StreamWriter in a base class. This of course will not work for you because your test case is not a standard finalization, but is a program exit, meaning .NET does what it wants when it wants. Instead, you should catch the exit event, dispose of this class, then return, to guarantee that things are disposed in the correct order. You should also check if the StreamWriter is already closed in the finalizer in case the program aborts due to an error.

How can I stop IIS 7 locking .XSLT file in C#

I have the following lines of code:
xslt.Load(XmlReader.Create(new FileStream(#"C:\website\TransList.xslt", System.IO.FileMode.Open)));
xslt.Transform(mydoc.CreateReader(),null, sw);
It works fine, if I stop the project and launch it again, I get the following error:
[System.IO.IOException] = {"The process cannot access the file 'C:\website\TransList.xslt' because it is being used by another process."}
I then have have to goto the command line and do a IISRESET to get, I can also reset the app pool, this is easiest at this time as this is just my dev box.
Now I do have the call in a try catch statement, but I cannot access the xslt object in the handler.
The xslt object doesn't seem to have a close or dispose method.
The garbage collector never gets a shot at it , it seems.
Any ideas?
You will need to close your FileStream and Reader, either explicitly using .Close() or via a using statement:
using (FileStream fs = new FileStream(#"C:\website\TransList.xslt", System.IO.FileMode.Open))
{
xslt.Load(XmlReader.Create(fs));
using (var reader = mydoc.CreateReader())
{
xslt.Transform(reader, null, sw);
}
}
There is no need to explicitly create a FileStream and an XmlReader, if you know the file location then you can simply pass that to the Load method, using this overload:
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(#"C:\website\Translist.xslt");
If you think you need to create a FileStream and an XmlReader then I agree with the suggestions already made, use the 'using' statement to properly close and dispose of those objects.
Filestream implements IDisposable and requires you to invoke Dispose to release external resources as well as implicit;y invoke close(). You should wrap your instantiation of Filestream in a using block as it ensures Dispose is invoked even if an exception is raised. To answer your question though, since you did not close the filestream, your process, presumably the w3wp.exe process still has a handle on the file stream and the only way you can release is it to reset iis or recycle the app pool. For future reference, just wrap the filestream in a using block to be safe.

Problem disposing of socket / finalising twice?

I'm working with some code (not mine I hasten to add, I don't trust this much at all) for a class which opens a socket, makes requests and listens for responses, which is throwing an exception in a way I can't comprehend when tested in xunit. I assume the same exception happens "live" but the class is referenced by a singleton so it is probably just hidden.
The problem manifests as "System.CannotUnloadAppDomainException: Error while unloading appdomain" in xunit and the inner exception is "System.ObjectDisposedException" thrown (essentially) inside the finaliser when closing the socket! There are no other reference to the socket which call close and dispose is protected on the Socket class so I'm not clear how else the object could be disposed.
Further, if I merely catch and absorb the ObjectDisposedException xunit terminates when it hits the line to close the listener thread.
I just don't get how the Socket can be disposed before it's asked to close.
My knowledge of sockets is only what I've learnt since finding this problem, so I don't know if I've provided everything SO might need. LMK if not!
public class Foo
{
private Socket sock = null;
private Thread tListenerThread = null
private bool bInitialised;
private Object InitLock = null;
private Object DeInitLock = null;
public Foo()
{
bInitialised = false;
InitLock = new Object();
DeInitLock = new Object();
}
public bool initialise()
{
if (null == InitLock)
return false;
lock (InitLock)
{
if (bInitialised)
return false;
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 8);
sock.Bind( /*localIpEndPoint*/);
sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(mcIP));
tListenerThread = new Thread(new ThreadStart(listener));
tListenerThread.Start();
bInitialised = true;
return true;
}
}
~Foo()
{
if (bInitialised)
deInitialise();
}
private void deInitialise()
{
if (null == DeInitLock)
return;
lock (DeInitLock)
{
if (bInitialised)
{
sock.Shutdown(SocketShutdown.Both); //throws System.ObjectDisposedException
sock.Close();
tListenerThread.Abort(); //terminates xunit test!
tListenerThread = null;
sock = null;
bInitialised = false;
}
}
}
}
If this object is eligible for garbage collection and there are no other references to the Socket, then the socket's finalizer may well run before your object's finalizer. I suspect that's what's happened here.
It's generally a bad idea (IMO) to do this much work in a finalizer. I can't remember the last time I implemented a finalizer at all - if you implement IDisposable, you should be fine unless you have direct references to unmanaged resources, which are almost always in the form of IntPtrs. Orderly shutdown should be the norm - a finalizer should only usually run if either the program is shutting down, or someone has forgotten to dispose of the instance to start with.
(I know you clarified at the start that this isn't your code - I just thought I'd explain why it's problematic. Apologies if you already knew some/all of this.)
Because of the way the garbage collector and finalizers work, finalizers must only be used if your class is the direct owner of an unmanaged resource such as a Window Handle, a GDI object, a global handle or any other kind of IntPtr.
A finalizer must not try to dispose or even use a managed resource or you will risk calling a finalized or disposed object.
I highly recommend you to read this very important Microsoft article for more detail on how garbage collection works. Also, this is the MSDN reference on Implementing Finalize and Dispose to Clean Up Unmanaged Resources, look carefully for the recommendations at the bottom.
In a nutshell:
If your object is holding an unmanaged resource, you should implement IDisposable and you must implement Finalizer.
If your object is holding an IDiposable object, it should also implements IDisposable on it's own and dispose that object explicitly.
If your object is holding both an unmanaged and a disposable, the finalizer must call two diferent version of Dispose, one that release disposable and unmanaged, the other only unmanaged. This is usually done using a Dispose(bool) function called by Dipose() and Finalizer().
The Finalizer must never use any other resource than the unmanaged resource being released and self. Failing to do so will risk referencing collected or disposed objects, since an object is temporarily ressurected prior to finalization.
New info: this looks like I'm having two problems actually, but the thread one appears to be rather toxic.
From the MSDN link above:
"ThreadAbortException is a special
exception that can be caught, but it
will automatically be raised again at
the end of the catch block."
Some very interesting community content also at that link including "Thread.Abort is a Sign of a Poorly Designed Program".
So at least I have some ammo to get this changed now :)

Categories