Wednesday, August 25, 2010

Lazy(Of T) class in .Net Framework4.0

.Net Framework provides us with a new class called Lazy<T> which is used to initialize the object in lazy pace. It includes the ability to initialize the value types and to use null values. Using this class, we could implement complex navigation related applications very effectively with less memory use. For instance, consider the situation like I have a property which holds array of user controls(Approx 50 User Controls) in Silverlight application. In this instance, need to display five user controls in main page, but need to initiate all these fifty user controls to get the actual references while application load since I need to bind some elements between user controls. At the same time, rest of the user controls will be displayed when user navigate explicitly.

If we implement such a application using typical .Net property declaration/initialization without using the Lazy class, all the user control will be initialized when we use new keyword while adding items in my array property. Below is the typical .Net initialization.

// Property declaration
private UserControl[] loadMyUserControl;
public UserControl[] LoadMyUserControl
{
get
{
return loadMyUserControl;
}
set
{
loadMyUserControl = value;
}
}

// Initializing property.
public MainPage()
{

InitializeComponent();
var userControls = new UserControl[]
{
new UserControl1(),
new UserControl2(),
new UserControl3()
};
}

In this approach, my application consumes unnecessary memory(Nearly 45 user control memory) when user open my application and closes without navigating into other pages.

But Lazy initialization occurs the first time the Lazy<T>.Value property is accessed or the Lazy<T>.ToString method is called. For my scenario, five user controls instance and memory only created while loading my application. Rest of the user controls will be created when user navigate to the corresponding page through navigation link from my main page. Below is the code snippet for lazy load.

// Property declaration
private Lazy<UserControl>[] loadMyUserControl;
public Lazy<UserControl>[] LoadMyUserControl
{
get
{
return loadMyUserControl;
}
set
{
loadMyUserControl = value;
}
}

// Initializing property.
public MainPage()
{
InitializeComponent();
LoadMyUserControl = new Lazy<UserControl>[]
{
new Lazy<UserControl>(() => {return new UserControl1();
}),
new Lazy<UserControl>(() => {return new UserControl2();
}),
new Lazy<UserControl>(() => {return new UserControl3();
})
};
}

Now I am going to load my user controls based on navigation at runtime as below mentioned.

// Loading my fifth user control on button click
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (!TopPanel.Children.Contains(LoadMyUserControl[5].Value))
TopPanel.Children.Add(LoadMyUserControl[5].Value);
}

Note : TopPanel is the stack panel which is in main page of the application. See the demo sample for more idea.

Run the demo app and click “Status” button. Check the status of user controls. Still all the user controls are not loaded as shown in below mentioned snap.

InitialLoad

Click “Load UserControl1” button and check the status. Now you could see, first user control loaded in view and status has been changed as True. What a great feature in framework4.0. :)

FirstLoaded

You can refer this in msdn documentation for more idea about Lazy class.

Here is the simple real time Silverlight sample which illustrates the same.

Enjoy :)

Thanks,

Venugopal.

No comments:

Post a Comment