Is it safe to dispose the Icon after calling Icon.ToBitmap()? - c#

After calling System.Drawing.Icon.ToBitmap() to create an image, is it safe to dispose the original Icon?

The method converts an Icon to a new Bitmap object, so there will be no reference from the Bitmap to the Icon.
So yes, it is safe to dispose the Icon.

Yes. Icon.ToBitmap draws the Icon to a new Bitmap object so it is safe to dispose it afterwards.
Edit:
Looking at the Icon.ToBitmap() method in Reflector was interesting. I expected it to be a simple Graphics.DrawImage or Graphics.DrawIcon call but it is more involved than that. As long as it is possible the function will do a memory copy of the icon image data instead, but it will revert to a Graphics.DrawImage or Graphics.DrawIcon call if it cannot perform the copy. The memory copy is much faster so that is obviously the reason, but this makes the code much harder to read.

Yes.
If you don't need the icon any more, and have the bitmap stored somewhere, you're fine.

Related

Does SharpDX.Direct2D1.GeometrySink need to be Disposed explicitly?

I'm using Direct2D through SharpDX to do some simple line drawings. I create a PathGeometry, then call Open() to get a GeometrySink and add lines to the sink. GeometrySinks are Disposable, so this is how I thought I should do it:
var linePath = new D2D.PathGeometry(D2dFactory);
using (var sink = linePath.Open())
{
sink.BeginFigure(point0, D2D.FigureBegin.Hollow);
sink.AddLine(point1);
sink.AddLine(point2);
sink.EndFigure(D2D.FigureEnd.Open);
sink.Close();
}
This code works, but VS 2012's Code Analysis says that I should not Dispose the GeometrySink two times. Is that really happening here? Maybe when I call sink.Close()? If that's the case, I should get rid of the using() statement. What's the right way to use GeometrySink ?
I've profiled a SharpDx application with Ants profiler, the GeometrySink objects are dangling in memory, after calling Dispose() explicitly on the GeometrySink before disposing the geometry itself I've profiled again and no more GeometrySink objects were in memory. So the simple answer is YES.
I believe your sink.Close is calling the Dispose method as well as using() is triggering it.

Free Memory after ImageBrush was set to null in WPF

In my app(music player) i have feature called "Game Mode" which stops every background operations except playing music and i wanna free some memory too.
E.g.
I have Background Image on Base Grid in my window which i set that way
BaseGrid.Background = new ImageBrush("the image");
In GameMode method i do something like this
BaseGrid.Background = null;
GC.Collect();
but it didnt free any memory when first time called, when i call the method second time it works, or if i paste the MessageBox.Show method between nulling and GC.Collect it works too.
So my question is.
Is setting Background to null Asynchronous operation that takes some time and GC.Collect didnt see unused object when its called so early after nulling or what another problem it can be?
When ever you call
GC.Collect();
you should call
GC.WaitForPendingFinalizer()
also
Use:
GC.WaitForPendingFinalizer();

RemoveAt(x); Does it dispose the element x?

I have a Cache to store the most two recent images every time the user clicks the next image, Does the "RemoveAt(x)" dispose the x image, or what I want is for the removed image not to be in memory. to be totally removed.
List<Image> BackimageList = new List<Image>();
private void BackimageListCache(Image img)
{
BackimageList.Add(img);
if (BackimageList.Count > 2)
{
BackimageList.RemoveAt(0); //oldest image has index 0
}
}
Collections in .NET do not "own" an object. So they cannot assume that the object isn't used anywhere else, they can thus not dispose the object. Ownership rules are entirely your own to implement. Which does imply that you also have to be sure the the image isn't, say, displayed in a PictureBox.
Ensuring the image doesn't occupy any memory anymore is iffy as well. You cannot manage memory yourself, it is the job of the garbage collector. However, Image uses a rather substantial amount of unmanaged memory to store the pixel data, that memory does get released when you call Dispose(). The managed part of Image stays in memory until the GC gets to it. It is small.
The RemoveAt method does not call Dispose on the image. You will have to dispose it yourself before you call RemoveAt.
Edit
If the type implements IDisposable, then to dispose it you write
BackImageList[0].Dispose();
BackImageList.RemoveAt(0);
RemoveAt(0) does, essentially:
for (int i = 1; i < BackImageList.Count; ++i)
{
BackImageList[i-1] = BackImageList[i];
}
BackImageList.Count--;
That's all done internally, of course. You can't set the Count property. It's done by the RemoveAt method.
There is no need to set the value to null before calling RemoveAt.

Form.ShowDialog() and dispose

If I have a method like this:
public void Show()
{
Form1 f = new Form1();
f.ShowDialog();
}
Do I still need to call dispose on the form even though it will go out of scope, which will be eligible for garbage collection.
From some testing, calling this Show() multiple times .. at some point it seems like the GC collects it since I can see the memory spiking then it goes down at some point in time.
From MSDN it seems to say you MUST call dispose when the form is not needed anymore.
What tends to happen is if the item has purely managed resources, calling dispose is not necessarily required, but is strongly advised because it makes disposal deterministic. It isn't always required (in a technical sense) because those managed resources would likely themselves now be eligible for GC, or there is actually nothing to dispose by default and it's an extensibility point.
For unmanaged resources, the Dispose Pattern advises implementing a finalizer, which will be called on GC. If types do not implement the finalizer and dispose is not called, then it is possible (well, very likely) that resources would be left unhandled. Finalizers are the last chance offered by the runtime for clearing your stuff up - they are also time-limited.
Note, that it does not make GC or managed memory reclamation deterministic, disposal is not delete from C++. A disposed item could be a long way away from actually being collected. However, in the managed world, you don't care about deterministic collection, only resource management - in other words, disposal.
That said, I always make sure I call Dispose or use a using statement if a type is disposable, regardless of whether it uses managed or unmanaged resources - it is the expected convention:
public void Show()
{
using (var f = new Form1())
{
f.ShowDialog();
} // Disposal, even on exceptions or nested return statements, occurs here.
}
Update:
After a discussion with Servy I feel I have to express this point as the reasoning behind my advice of disposing where possible. In the case of MemoryStream, it is clearly a disposable type, but actually does not dispose of anything currently.
Relying on this, however, is to rely on the implementation of MemoryStream. Were this to change to include an unmanaged resource, this would then mean that a reliance on MemoryStream not having anything to dispose becomes problematic.
Where possible (as is the case with IDisposable) I prefer to rely on the public contract. Working against the contract in this instance would mean I am safe from underlying implementation changes.
Although you rarely have to manually dispose in C# imo, you could try it like this:
public void Show()
{
using (Form1 f = new Form1())
{
f.ShowDialog();
}
}
Then at the last accolade of the using part it will get disposed of automatically.
ShowDialog has side effect of keeping the GDI objects alive. In order to avoid GDI leak we need to dispose the ShowDialog appropriately. Where as Show method does not have any implication and GDI will be released appropriately. It is recommended to dispose the showDialog and do not rely on Garbage collector.
You could simply do:
using (var f = new Form1())
f.ShowDialog();
If you want to explicitly dispose, use
using(Form1 f = new Form1()){
f.ShowDialog();
}
This ensures Dispose() is called, as well as it occurs immediately
In your specific example, no, it's unlikely that it would be particularly useful. Forms do not hold onto a significant amount of resources, so if it takes a little bit longer for some portion of it's code to get cleaned up it isn't going to cause a problem. If that form just happens to be holding onto a control that is used to, say, play a video, then maybe it's actually holding onto some significant number of resources, and if you actually do dispose of those resources in the dispose method then it's worth taking the time to call dispose. For 99% of your forms though, their Dispose method will be empty, and whether you call it or not is unlikely to have any (or any noticeable) effect on your program.
The reason that it's there is primarily to enable the ability to dispose of resources in those 1% of cases where it's important.
It's also worth noting that when a Form is closed its Dispose method is already being called. You would only ever need to add a using or explicit Dispose call if you want to dispose of a Forms resources before that form is closed. (That sounds like a generally bad idea to me). This is easy enough to test. Just create a project with two forms. Have the second form attach an event handler to the Disposing event and show a message box or something. Then when you create an instance of that form and show it (as a dialog or not) you'll see that when you close it the message box will pop up right away, even if you keep the 'Form' instance around and without you ever needing to add a using or Dispose call.
Yes, you need and MUST call Dispose or use using statement, otherwise it can be, that instance remains in memory.
You can check it, if you put a Timer to the form and set a break point in the Timer.Tick handler. Even after closing the form without Dispose the handler will be called.

Bitmap class doesn't dispose stream?

So, after discovering that the Bitmap class expects the original stream to stay open for the life of the image or bitmap, I decided to find out if the Bitmap class actually closes the stream when it is disposed.
Looking at the source code, the Bitmap and Image classes create a GPStream instance to wrap the stream, but do not store a reference to either the GPStream or the Stream instance.
num = SafeNativeMethods.Gdip.GdipLoadImageFromStreamICM(new GPStream(stream), out zero);
Now, the GPStream class (internal), does not implement a Release or Dispose method - nothing that would allow GDI to close or dispose of the stream. And since the Image/Bitmap class doesn't keep a reference to the GPStream instance, it seems that there is absolutely no way for either GDI, Drawing.Bitmap, or Drawing.Stream to close the stream properly.
I could subclass Bitmap to fix this, but, oh wait, it's sealed.
Please tell me I'm wrong, and that MS didn't just make it impossible to write code that doesn't leak resources with their API.
Keep in mind (a), Bitmap has no managed reference to the stream, meaning GC will collect it while it is still in use, and (b) .NET APIs take Bitmap/Image references and aren't deterministic about when they're done with them.
Since you supply the stream in this example, I'd imagine you are responsible for disposing it.
It is a good practice to have the method that opens a stream, close it as well. That way it is easier to keep track of leaks. It would be quite strange to have an other object closing the stream that you opened.
Because bitmap can't guarantee in which order the destructor is called it will not close the stream because it may already have been closed with its own destructor during garbage collection. Jeffrey Richter's CLR via C# has a chapter on memory management that explains with much more clarity than I can.
An easy workaround to the problem is:
var image = new Bitmap(stream);
image.Tag = stream;
Now the stream is referenced by the image and won't be garbage collected before the image is. If your stream happens to be a MemoryStream, it doesn't need to be disposed (its Dispose is a no-op). If not, you can dispose it when you dispose the image, or just let the GC do it when it gets around to it.

Categories

Resources