I have a complex program in which I have to first create, then use wrappers around bitmaps and send them across a lot of different classes. The problem in the end is deciding which classes should dispose the bitmaps. Most of the time the end classes don't know if they can indeed dispose the bitmap as the same bitmap can be used in several places. Also, I can't just copy the bitmaps because this is a kind of resource intensive algorithm and doing it would be dead slow.
I looked up on reflector for Image/Bitmap's implementations and they seem to use the 开发者_运维知识库Dispose Pattern. So, even if I don't call Dispose(), the CLR will eventually call it some other time.
Is it too bad if I just let the bitmaps be as they are, and let the finalizer take care of them?
Your main problem here seems to be your design, but it is probably too late and/or too expensive to fix now. But in general, avoid holding on to resources for too long.
Since you are using wrappers, you could take a look at reference counting as a design pattern. Any holding object could register & unregister its interest in the bitmap and you can Dispose when the ref count drops to 0.
But the easy way here is to just let the GC do the work. Just make sure all referencing fields to the wrappers are null-ed asap.
So, even if I don't call Dispose(), the CLR will eventually call it some other time.
The Finalizer and the Dispose method are two different things. It "should" do this, but you can't say for certain that it will. You can't assume this, you'll have to check on a case by case basis. From what you say, in this case it sounds like it does.
Is it too bad if I just let the bitmaps be as they are, and let the finalizer take care of them?
Yes it is, because specifying a finalizer causes extra work for the Garbage Collector. It will automatically promote it to the next generation of the CG, meaning resources won't be released as soon as they could. Normally, when someone implements Dispose they suppress the finalizer call which will prevent this.
Anytime an object implements IDisposable, it should be encased in a using statement.
using(var bitmap = new BitMap())
{
....
}
In this case, since the dispose method is in the finalizer, and you really really need to, you can not use the dispose method and let the finalizer take care of it. It's not good, but you can do it. Based on what you say, this may be the best course of action without refactoring the code.
What is the lifetime of the bitmaps? In other words, what triggers the creation of the bitmaps and what "events" take place between then and when they can be safely destroyed?
If there are no user/external events taking place between creation and end of life, it would be best if the code could be structured such that the code that creates the bitmaps also destroys them.
In C#, it would be best to wrap them in a using
statement:
using (Bitmap bitmap = CreateBitmap())
{
DoWork(bitmap);
}
This guarantees that the bitmap is only retained for as long as it is needed and no more.
If user/external events occur between creation and end of life (and the bitmaps need to be accessed in the processing opf those events), the situation is not this simple but this would also imply that you're keeping a persistant reference to the bitmaps somewhere which would prevent them from being garbage collected anyway.
Well based on what I understood from your question I would suggest you following
Extend the IDisposable interface in the classes in which you are retaining the class level variable of the image object and dispose that image object in the Dispose() method.
I also think that you do not need to worry about the bitmap object you are passing to other methods, you do not need to dispose it in that specific class. Just make sure you are disposing it in the class which is creating the instance of the bitmap.
Hope this will help you.
精彩评论