I'm developing an application to manage a player card-library from an online game. Each card has an image that is stored on disk with a numeric code, for example, the card with ID=1234 has his image stored as 1234.png and all the images are stored on the same folder.
As of now there are more than 3500 images for a total of 1 GB of hard disk usage.
The app doesn't need all the images loaded on memory, but depending on the context it may need from 8 to 100 images loaded on screen, and the next moment it may need a 100 different images.
As of now the images are loaded using IValueConverter
and DataTemplate
without storing on code behind the image, so everytime an image is needed, it is loaded from disk.
That is the current state of the project.
Now this is the code that I want to implement:
public class ImageAccessor
{
private string Filepath;
private Dictionary<int, WeakReference> References;
public ImageAccessor(string filepath)
{
Filepath = filepath;
}
public BitmapImage GetImage(int id)
{
BitmapImage image = null;
WeakReference reference = null;
if (!References.TryGetValue(id, out reference))
{
image = GetFromDisk(id);
reference = new WeakReference(image);
References[id] = reference;
}
else
{
image = reference.Target as BitmapImage;
if (image == null)
{
image = GetFromDisk(id);
reference.Target = image;
}
}
return image;
}
private BitmapImage GetFromDisk(int id)
{
Uri uri = new Uri(Filepath + id + ".png");
return new BitmapImage(uri);
}
}
I don't want to implement a singleton of that class but for now let's assume that my project always uses the same instance.
Everywhere that I read about WeakReference
they recommend using it for "a single large object", but what if I want to use it on "a lot of relative small-medium size objects (200~500kb each)". Except from the advice of using them for big objects, those images meet the rest of the requirements:
- Having all of them all the time on memory would be very costly (1GB on RAM)
- Some images may not be used for the entire life of the app
- Some images may be used only one or a couple of times
- Some images may be used lots of times
And by using an image I mean displaying it on a Image control
I've never worked with weak references, and I still need to do some benchmarks to see if they are worth it, but I want to know if this code:
- Is safe?
- May incur on memory problems?
- It can be improved?
For the sake of simplicity assume this:
- The filepaths will always be correct
- Every ID will correspond to an existing image always
- Images will not be modified