Joe Rattz to the Rescue

April 24, 2008

In my previous post, I showed a simple way to create animations in WPF using a sequence of images. That demo app used a LINQ query to get a sequence of BitmapImage objects based on the PNG files in a certain folder. Joe Rattz, the LINQ guru, dropped a comment on that post and also included his e-mail address. Big mistake!! 😀

I sent him an e-mail, asking if the BitmapImage objects in that LINQ query are created every time a new enumerator is created and iterated over. When I send an expert an e-mail I never expect to hear back. I certainly don’t reply to all of the questions that people send me! There are only 24 hours in a day. 😛

Luckily, Joe replied. Thanks Joe! It turns out that the answer is yes, the LINQ query is creating new BitmapImage objects for each new enumerator, as the enumerator is iterated. This is not a good thing. Since my demo app repeats the animation indefinitely, a potentially huge number of unnecessary BitmapImage objects were being created by the LINQ query.

The reason for all this is the fact that my LINQ query was only using deferred query operators. LINQ has deferred and non-deferred operators, as Joe’s book explains. If you use all deferred operators, the query’s results are not cached. Every time you iterate the resultset the query creates new objects for you. In some cases that is what you want. In my case, it is undesirable.

Working around this turned out to be easy, especially since Joe e-mailed me the answer. 😉

I needed to apply a non-deferred operator to the query. This would cause the results of the query to be cached, so that all enumerators created against the query iterate the same set of objects. Here is the new code-behind for the demo app:

Notice how the entire LINQ query is wrapped in parenthesis and then a call to the ToList extension method is placed at the end. ToList is a non-deferred query operator, which is the magic that fixes the issue.

If you want the source code for this app, download it here. Be sure to change the file extension from .DOC to .ZIP and then decompress the file.