Tech Off Post

Single Post Permalink

View Thread: WPF Image Source cache problem?
  • User profile image

    Hi there. 

    I wrote a small WPF app and I have the following code that loads images for me:

    /// <summary>
            /// Loads an image from a path name
            /// </summary>
            /// <param name="relativePath">The path the the image</param>
            /// <returns>An instance of the class <see cref="ImageSource"/> that contains the loaded image</returns>
            public static ImageSource Load( string relativePath )
                //Test the cache if the internal cache is enabled
                ImageSource imageSource = useInternalCache? TryCache( relativePath ) : null;
                if ( imageSource != null )
                    return imageSource;

                Logger.Instance.Log( null, Logger.LogLevel.Debug, "Loading `" + relativePath + "'" );
                Uri uri = new Uri( "pack://siteoforigin:,,,/" + relativePath );
                string fileType = relativePath.Substring( relativePath.LastIndexOf( "." ) );
                //Create the image source from the filetype
                    if ( fileType == ".ico" )
                        IconBitmapDecoder ico = new IconBitmapDecoder( uri, BitmapCreateOptions.None, BitmapCacheOption.Default );
                        imageSource = ico.Frames[0];                    
                    else if ( fileType == ".bmp" )
                        imageSource = new BitmapImage( uri );
                    else if ( fileType == ".png" )
                        PngBitmapDecoder png = new PngBitmapDecoder( uri, BitmapCreateOptions.None, BitmapCacheOption.Default );
                        imageSource = png.Frames[0];
                    else if ( fileType == ".jpg" )
                        JpegBitmapDecoder jpg = new JpegBitmapDecoder( uri, BitmapCreateOptions.None, BitmapCacheOption.Default );
                        imageSource = jpg.Frames[0];
                        //TODO default cross or something
                        Logger.Instance.Log( null, Logger.LogLevel.Warn, "Image of type `" + fileType + "' is not supported" );
                catch ( Exception e )
                    Logger.Instance.Log( null, Logger.LogLevel.Warn, "Image load failed `" + relativePath + "' with exception: ", e );

                //Cache the image
                _imageCache[ExtractFileName( relativePath )] = imageSource;
                return imageSource;

    Firstly I would apreciate any criticism about the function. Really go to town, thats how I learn. Secondly that internal cache that I had to add there because if I load the same image twice I get an inner exeption on the lines that instantiate the new ImageSources.

    For example, 

    IconBitmapDecoder ico = new IconBitmapDecoder( uri, BitmapCreateOptions.None, BitmapCacheOption.Default );

    would throw a inner exception causing the image not to load. 

    Further more, after enabling Common Language Runtime Exceptions those lines brings down the app. Looking at the stack trace it seems that the exception happnes somewhere down the caching code path. Could it be a caching problem? I tried fiddeling with those caching settings in the call but those seem to have no effect.

    What is even more disturbing is when you step to those lines, the inner exception would not happen and the image would load properly. Making debugging the problem even more confusing. 

    Another weird thing is that after loading the image, if you access the image in any way, for instance 'if( image.height > ) doSomething;' then the inner exception also fails to happen and the image loads. 

    I am just posting the problem here for in case someone else ever come across the problem.  While typing this email I realized that I set my target Framework to 3.0, I would test it on target Framework 3.5 and report if I get the same behaviour.