When working with images in Silverlight it might be sometimes required to prevent caching. As long you just present some photos the caching feature is definitely a great one. However if you bind to frequently changing images like charts, you will need to download images on each request or binding refresh. In such cases you could experience few problems:
1. What ever you do Silverlight will never download the image again after it is cached once.
2. If you append dynamic arguments,SIlverlight will sometimes download images, but sometime just show them from cache.
Problem Description
To illustrate the problem let’s use image with following binding:
<Image Stretch="Uniform" Grid.Column="1" Visibility="Visible" Source="{Binding ImageUri}"/>
Once the image is downloaded (after first binding) image is persisted in the browser cache. That means image will never be downloaded again. SOme people believe, that image is downloaded again on every browser start, but this is not true. This explains issue [1].
To workaround this problem I tried using of different simple techniques like appending of arguments to image name:
myBIndingEntity.ImageUri += DateTime.Now.Ticks;
Unfortinatelly browser cache has very interesting algorithm to check if one file is in cache. For example the file name abc.jpeg?blablabla
will be stored in the cache as abc[1].jpeg. So, by trying different combinations of parameters image will be cached as abc[1].jpeg, abc[2].jpeg etc.
Depending on how you have created the dynamic name of the new URI it can happen that the new URI cause browser to treat it as abc.jpeg, which never has been cached. This cause the browser to download the image once and persist it under name abc.jpeg.
On the next dynamic name every transformation to abc[k] ( 1 < k < N) will prebent the Silverlight application to download image.
In this case you will have a feeling that images are sometimes downloaded and sometimes just shown from the cache. This explains the issue [2].
Following picture shows what the browser cache looks like in the case of image SingleSlide_256_t4trust-aLifePass-Flyer.jpg :
One more thing. If the source in binding of the image is relative one, Silverlight will start donwloading of the image with URI without of any additional parameters which you have added.
For example the image ImageName.jpg?MyParam=abcefg will be sent over network as (notice no arguments are appended):
GET /Daenet.SLPresentationManagerGui.Web/ClientBin/ImageName.jpg HTTP/1.1
Solution
To solve the problem Microsoft provided property BitmapCreateOptions.IgnoreImageCache. Unfortunately this does not work for some reason.
I figured out that Silverlight always do caching if the image is bind as relative one. To make it working I implemented the convertEr which binds the image as absolute one:
Here is the binding via converter:
<Image Stretch="Uniform" Grid.Column="1" Visibility="Visible"
Source="{Binding ImageUri, Converter={StaticResource ImageSourceConverter}}"/>
… and here is the converter itself:
public object Convert( object value, Type targetType,
object parameter,
System.Globalization.CultureInfo culture )
{
if (value == null)
return null;
Image img = new Image(); Uri uri = new Uri(“http://host/virtfolder/”, UriKind.Absolute);
BitmapImage bi = new System.Windows.Media.Imaging.BitmapImage(uri);
//bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache; (This does not work anyhow!)
img.Source = bi;
return img.Source;
}
Notice that property CreateOptions is commented out, because it does not work. After this is done, take a look in Fiddler.You will notice, that the image is downloaded on every single binding. Using of dynamic arguments is important in this example. They cause Silverlight to use other way when working with the cache:
GET /Daenet.SLPresentationManagerGui.Web/ClientBin/PresentationThumbnails/80bede99-75bb-4225-95ff-d15b3170c426/ImageName.jpg?633951716001752447 HTTP/1.1
Hope this helps… :)
Posted
Nov 30 2009, 10:23 PM
by
Damir Dobric