I have an application that loads some objects and displays them in a grid. One of those objects is a preview image which could be either a local image file or an image file on a web location. Right now it is working but the performance isn't very good when scrolling because whenever a new item scrolls into view it has to load the preview which takes a second or two.
What I am trying to accomplish is that the box for the preview would show up and start loading the preview on a background thread when it is scrolled into view. When the image is loaded it would notify (via property change event in the view model) and the image would come into place. This way the UI remains responsive and the preview is just blank until it loads and then it shows up. I have the getter for the bound property starting the backgroundWorker if the image isn't already cached, and the worker routine is as follows (_previewCache is the backing property for the bound preview):
void bw_LoadPreview_DoWork(object sender, DoWorkEventArgs e)
{
BitmapImage _tempCache = new BitmapImage(new Uri(PreviewImagePath, UriKind.RelativeOrAbsolute));
if (_tempCache.CanFreeze)
{
_tempCache.Freeze();
Dispatcher.CurrentDispatcher.Invoke((Action)(delegate { _previewCache = _tempCache; }));
}
}
This seems to work pretty well on local files, though it takes a little longer than I would expect for the images to appear, but the UI remains responsive. However when the image is a web path, it always ends up as _tempCache.CanFreeze = false so it skips it and doesn't load. If I try to do the invoke without freezing, it says it can't use the object because it's owned by a different thread.
What am I missing? How do you load a web based image this way? Or is there a better way to approach this issue that I'm not seeing? Any help is greatly appreciated.