Click here to Skip to main content
12,296,307 members (63,952 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


26 bookmarked

Lazy Alternatives - LazyAndWeak and BackgroundLoader

, 1 Dec 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
This article will present two alternatives to Lazy.


This article will present two alternatives to Lazy. One of them is focused on low memory use and the other focused on responsiveness.


.NET 4 added the Lazy class. Its purpose is to allow fast load times and reduce memory consumption.

But, should I say that I consider Lazy class... too lazy? There are two problems that I see when using the Lazy class:

  1. The application loads fast, but then you must wait for each item that you access for the first time.
  2. If you load an item to use it only once, it will be kept in memory forever (ok... until the lazy object itself is collected).

So, to solve those problems, I decided to create my own solution, which I will present here.

Lazy Alternatives

I really wanted to create a solution that is both responsive and that avoids using memory when it is not needed. But unfortunately that's impossible... at least for me and as a generic purpose solution. But I can solve one of those problems at a time.

So I did it, as two different classes:

  • LazyAndWeak - Better memory management
  • BackgroundLoader - Better responsiveness


For human beings, being lazy is usually bad. Being weak too is even worse. But for programming languages, being lazy and weak is good, especially when we want to save memory.

LazyAndWeak only creates its Value when it is first requested, as happens with Lazy class. But it also stores the value as a weak-reference, so it can be collected if memory is needed. Ok, it is a bit more than that. To avoid values to be collected at each garbage collection, I use my GCUtils.KeepAlive method so recently used items are not collected in the next full collection, so constantly used items will always be in memory, even after a full collection.

The big downside here is that after the item is unloaded from memory, if it is needed again, the user will need to wait again and any value that was stored in such item will be lost. So, it is very important that the constructor/creator knows how to get the most up-to-date information.


The BackgroundLoader class goes in the opposite direction of LazyAndWeak. Instead of creating items only when requested and then allowing them to die, it tries to load all items in the background, trying not to affect performance of the application and then keeps them there. So, you load the application in a very fast manner, similar to what happens to any Lazy alternative but then when a CPU is idle, it starts loading the items that you didn't use yet.

I say that it goes in the opposite direction because it will not save any memory, as sooner or later all the items will be loaded and kept in memory. But except from the very first item (in case the user requests it as soon the application is loaded), the user will not need to wait for items to load. It opens the application (in a very fast manner), maybe wait for the very first operation to load its items but, later, any other operation will be done instantly as the items will be already loaded.

When To Use Each One?

In my opinion, never use Lazy. Maybe I am too drastic, but I don't see a real situation were Lazy only will be better. For example, if your application has 1000 menu items, each one with a slow load-time, and your users are probably only using 10 of those 1000 menu items, then it is OK.

But what happens when the user does load those 1000 items? They will be kept in memory forever. So, the user will need to wait 1000 times and then those will be there forever (so new requests will not wait).

But if those 1000 items consume too much memory, I'll say that you should use LazyAndWeak, after all the computer gets slower when running out-of-memory. If you think it is OK to keep all of them in memory, then use BackgroundLoader as the user will wait for the program to load, maybe will wait for the first menu item to load... and if he keeps enough time there, when he uses any other item it will be already in memory, without the need to wait again.

In fact, for very large projects, I usually open the application, go out for a while and then return, expecting everything to be loaded. I consider it frustrating that, in Visual Studio, I end-up waiting again when I try to load an ASP.NET project for the first time or a WPF one.


I know CodeProject is for code... but should I really show the code here? I think explaining the basic idea is enough. So, I will only explain the idea.

LazyAndWeak uses a lock when creating the value (so two threads will not create duplicate values). When accessing the Value, a call to GCUtils.KeepAlive is made. I explained that class in one of my first articles, WeakReferences as a Good Caching Mechanism. The main problem of using WeakReferences only is that items are discarded at every collection, even if they were recently used. This class forbids them to be collected at the next collection but allows them to be collected if a second collection happens and they are still unused.

BackgroundLoader is harder. A "loader" thread is created. Each time a LazyLoader is created, it registers itself inside that thread and sets an event (ManagedAutoResetEvent) so the loader thread starts to run. If 1000 items are registered, they will be loaded in order (there is not the risk of 1000 threads trying to load their items). This class also uses locking when accessing its Value so if it is not loaded yet, it loads it immediately and removes this BackgroundLoader instance from the loader class, as it will be already loaded.

Also, there is the problem that you may create the background loader and then you discard it (in the sample project, when you change from one directory to another). That's why I implemented the IDisposable interface. If the item is not loaded yet, it is in the list of "to load" items. If you discard it, it simply removes such item from the "to load" list.

How to Use the Classes

Using those classes is very similar to using the .NET Lazy class. You simply create the LazyAndWeak<SomeType> or BackgroundLoader<SomeType> at the very first moment, probably with a declaration like this:

private readonly LazyAndWeak<SomeType> field = new LazyAndWeak<SomeType>();

And when you need to access the SomeType instance, you must access the Value property of the created field.

It is important that SomeType has a default constructor or that you give a creator delegate to it, or you will get an exception. Also, as happens with lazy, those helper objects are only useful to hold slow loading or memory-hungry objects. Don't use them for fast and small objects, as the helper objects themselves consume memory.


The attached sample is a very simple image visualizer. Its purpose is only to show the differences of the various techniques.

When you enter any directory, all image names are read and some type of lazy-loading will be done. When just opening or scrolling large folders, you will see red lines instead of images. Red lines means such images are not still in memory.

If you force collection, already loaded images will be reloaded using LazyAndWeak (which shows it worked) but will not have any effects on BackgroundLoader or custom Lazy.

I forced a 100 milliseconds delay when loading images. That was on purpose to make the differences more visible as loading images is not that slow.

If you are using BackgroundLoader, when you change directory, it will stop loading the old files. That's why Dispose was needed. If I didn't do that, if I entered directory A, then B... B will only load after loading all (useless) A files.


  • 1st December, 2011: Initial version


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Paulo Zemek
Engineer Microsoft Corporation
United States United States
I started to program computers when I was 11 years old, as a hobbist, programming in AMOS Basic and Blitz Basic for Amiga.
At 12 I had my first try with assembler, but it was too difficult at the time. Then, in the same year, I learned C and, after learning C, I was finally able to learn assembler (for Motorola 680x0).
Not sure, but probably between 12 and 13, I started to learn C++. I always programmed "in an object oriented way", but using function pointers instead of virtual methods.

At 15 I started to learn Pascal at school and to use Delphi. At 16 I started my first internship (using Delphi). At 18 I started to work professionally using C++ and since then I've developed my programming skills as a professional developer in C++ and C#, generally creating libraries that help other developers do they work easier, faster and with less errors.

Now I just started working as a Senior Software Engineer at Microsoft.

Want more info or simply want to contact me?
Take a look at:
Or e-mail me at:

Codeproject MVP 2012, 2015 & 2016
Microsoft MVP 2013-2014 (now I work at Microsoft so I can't be a Microsoft MVP anymore)

You may also be interested in...

Comments and Discussions

QuestionReactive Extension (Rx)? Pin
unknowndentified101111-Dec-11 20:36
memberunknowndentified101111-Dec-11 20:36 
AnswerRe: Reactive Extension (Rx)? Pin
Paulo Zemek2-Dec-11 0:16
memberPaulo Zemek2-Dec-11 0:16 
SuggestionLazyAndWeakAndReactiveAndDependent (LWRD) Pin
AspDotNetDev1-Dec-11 9:02
protectorAspDotNetDev1-Dec-11 9:02 
GeneralRe: LazyAndWeakAndReactiveAndDependent (LWRD) Pin
Paulo Zemek1-Dec-11 9:41
memberPaulo Zemek1-Dec-11 9:41 
GeneralRe: LazyAndWeakAndReactiveAndDependent (LWRD) Pin
AspDotNetDev1-Dec-11 10:22
protectorAspDotNetDev1-Dec-11 10:22 
Lazy itself (and your alternatives) is really just a small class to consolidate functionality. My two variations would be the same. Of course you could implement them based on the existing three variations, having two more would provide that functionality out of the box.

Paulo Zemek wrote:
In fact, if you have a tree, were each child is composed of Lazy childs, you will need to instantiate the base node, to then request one sub-node, to then request another sub-node.

Right. IF you have a tree. That was just one example. The lazy/background dependency might be between objects which are themselves not dependent. For example, one might make printing functionality available to load once a grid has been loaded (because maybe people tend not to print unless there is a grid visible). One might also create many to many relationships for the dependencies. So printing functionality might be made available to load once a grid has been loaded or an image has been loaded, and either of those two things loading might also make available to load exporting to PDF functionality.

And this is an important point too: making something "available to load" doesn't necessarily load it. It could then wait for the computer to be idle, for example. And, it being made "available to load" is really just a hint... if some code explicitly asks for the value, it will load immediately even if it was not previously made available to load.

Paulo Zemek wrote:
Then the code that depends on the value should first check if the Lazy object is null or not

This is basically what the lazy class is there to avoid. You don't want to have to check for null. You want the lazy wrapper itself to exist and a request to the LazyWrapper.Value to either return the already created instance or a new instance. To clarify, the reactive lazy would only make available to load on some event (perhaps controlled by the helper class I demonstrated with). It might then wait for the computer to be idle or a call to blah.Value to instantiate the value.

Anyway, just some ideas for you to think about. Your article is already a neat idea and a complete article. Smile | :)
Somebody in an online forum wrote:
INTJs never really joke. They make a point. The joke is just a gift wrapper.

GeneralRe: LazyAndWeakAndReactiveAndDependent (LWRD) Pin
Paulo Zemek1-Dec-11 10:49
memberPaulo Zemek1-Dec-11 10:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160525.2 | Last Updated 1 Dec 2011
Article Copyright 2011 by Paulo Zemek
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid