Valentines Muncher

by Chad 15. February 2010 05:13

I have a fun post this week. At work we had a Valentine's Day event and all employees decorated Valentine bags. I saw this as an opportunity to build a robot using my Lego NXT set. I built and programmed the robot’s insides and my wife decorated and accessorized the robot’s outsides. Watch the video to see him in action.

Tags:

JustForFun

Event Handler Memory Leaks

by Chad 9. February 2010 06:18

Event handlers are a common cause of memory leaks in managed applications. It’s so easy to register an event handler, that sometimes we can forget what’s actually happening. There are three parties involved in eventing: the event source, a delegate, and the event sink.

The event source is the object that publishes notifications via an event. The event sink is the object that is interested in those notifications and knows how to respond to the event. The delegate is the object that enables the event source to communicate with the event sink.

Looking at the System.Delegateclass, we see that it has two properties: Target and Method. Target contains a reference to the event sink object and Method contains a MethodInfo object used to invoke the event handler method on the event sink object. When you use the C# statement eventSource.SomeEvent += new EventHandler(eventSink.SomeEventHandler); you are creating a new delegate with a reference to your event sink object and adding a reference to the delegate class to the event source object. The references look like this: event source > delegate > event sink.

The effect of this isn’t very visible when the lifetime of the event source and event sink are similar. However, when the event source lives much longer, say for the lifetime of the application, and the event sink only has a short lifetime, you can quickly leak memory because the event source will never release it’s reference to the event sink.

Consider this example

class View

{

    private string _name;

    public View(string name)

    {

        _name = name;

 

        // Register for CollectionChanged notifications; MASTER_COLLECTION

        // is static.

        Program.MASTER_COLLECTION.CollectionChanged +=

            new NotifyCollectionChangedEventHandler(

                masterCollection_CollectionChanged);

    }

 

    void masterCollection_CollectionChanged(object sender,

        NotifyCollectionChangedEventArgs e)

    {

        // Update view

        Console.WriteLine("{0}: {1} items.",

            _name,

            Program.MASTER_COLLECTION.Count);

    }

 

    ~View()

    {

        Console.WriteLine("View {0} Finalized.", _name);

    }

}

 

class Program

{

    public static readonly ObservableCollection<object> MASTER_COLLECTION

        = new ObservableCollection<object>();

 

    public void Run()

    {

        // Create two views

        View v1 = new View("v1");

        View v2 = new View("v2");

 

        // Raise CollectionChanged event

        MASTER_COLLECTION.Add(new object());

 

        // Release v1 & v2 references

        v1 = null;

        v2 = null;

 

        // Wait for Garbage collector to release memory

        GC.Collect();

        GC.WaitForPendingFinalizers();

 

        // Create v3

        View v3 = new View("v3");

 

        // Raise CollectionChanged event

        Console.WriteLine("We only expect v3 to be in memory.");

        MASTER_COLLECTION.Add(new object());

        v3 = null;

 

        // Wait for Garbage collector to release memory

        GC.Collect();

        GC.WaitForPendingFinalizers();

 

        Console.WriteLine("Example finished.");

        Console.ReadLine();

    }

 

 

    static void Main(string[] args)

    {

        Program p = new Program();

        p.Run();

    }

}

The output for this is:

v1: 1 items.
v2: 1 items.
We only expect v3 to be in memory.
v1: 2 items.
v2: 2 items.
v3: 2 items.
Example finished.
View v3 Finalized.
View v1 Finalized.
View v2 Finalized.

How to avoid this?
You need to keep this subtle problem in mind when designing your classes. To prevent these types of memory leaks, you’ll need to design mechanisms into your object’s lifecycle so that it can detach it’s event handlers. Detaching an event handler is as simple as using the –= operator. The difficult part is knowing when to detach. You can use the IDisposable pattern or expose a CleanUp() method or add lifecycle events to trigger the detach.

Tags: ,

.NET-Basics

Large Lists in WPF and WCF – Part Four

by Chad 1. February 2010 06:00

Wrapping Up
This is the final post of this series. In the previous post, I showed you how to add paging to your WCF service’s message contracts. I then showed a strategy for consuming paged results on the client asynchronously. This strategy will increase your end user’s perception of your application’s performance.

In this post, I will show you a client-side abstraction for consuming paged service operations. We’ll create a PagedRequestManager class that can be used to manage the requests of any paged service operation. The responsibility of this class is to keep track of the current page, request the next page, and publish notifications on the UI thread.

IPagedRequest and IPagedResponse
The first step in this process is to have Visual Studio create classes for your message contracts. To do this right-click your service reference and choose Configure Service Reference. In the Data Type section of the Service Reference Settings dialog, check the “Always generate message contracts” option. Visual Studio will now rebuild the proxy classes – this will likely break your client code so you’ll need to correct any build errors at this point.

Now we need to make all of our message contracts implement the same interfaces. For this we create two client-side interfaces: IPagedRequest and IPagedResponse. It’s important to realize that these are purely client-side interfaces who’s implementations simply map the interface properties to the appropriate message contract fields. This keeps the client-side paging requirements separate from the service’s.

public interface IPagedRequest

{

    PagingContext PageInfoState { get; set; }

}

public interface IPagedResponse

{

    PagingContext PageInfoState { get; }

    IEnumerable ResultItems { get; }

}

Below is a sample implementation for a paged response. The proxies generated for us by Visual Studio are partial classes, which enables us to extend them at design-time. To do this, create a new class with the same name (and namespace) as a message contract class and add the partial keyword to the class declaration. We’ll do this for the request and response message contracts for each service operation that supports paging. Notice that the ResultItems property is a loosely-typed IEnumerable; this keeps the interface simple so that it can be applied to responses that return any type of object – not just Foods.

public partial class GetAllFoodsResponse : IPagedResponse

{

    public PagingContext PageInfoState

    {

        get { return PageInfo; }

    }

 

    public System.Collections.IEnumerable ResultItems

    {

        get { return Results; }

    }

}

PagedRequestManager 
Next, we will create a class that knows how to process IPagedRequest and IPagedResponse messages.image I named this class the PagedRequestManager. At the heart of the PagedRequestManger is the AsyncOperationManger. The AsyncOperationManager class is a class that lives in System.ComponentModel (System.dll) and helps you manage concurrency in multithreaded applications. We’ll be using it to reliably dispatch updates from our worker thread back to the UI thread.

PagedRequestManager is a simple class that takes an IPagedRequest and IList. It then executes the request for all pages, adding the results from the paged response to the specified IList. After it’s loaded the last page, it fires an event to notify the UI that the operation has finished. Additionally, it supports cancelling the asynchronous operation at any time.

The sample below shows the paged request loop inside of the PagedRequestManager. This loop executes on a non-UI thread so that the UI isn’t waiting for the response to come back from the service. The asyncOp.Post(…) statement, uses the AsyncOperation class to load the results into the specified IList. The asyncOp object was created by the AsyncOperationManager and is smart enough to execute it’s delegate on the UI thread. This is important because the _asyncProcessResults delegate will add the ResultItems to a user-specified IList. In our example, this WPF list is an ObservableCollection. When the ObservableCollection fires it’s CollectionChanged events, we want to make sure those are fired on the UI thread.

do

{

    IPagedResponse response = client.ExecutePagedRequest(request);

 

    itemCount = response.ResultItems.OfType<object>().Count();

    asyncOp.Post(_asyncProcessResults, new object[]

        {

            response,

            resultsList,

            asyncOp

        });

 

    request.PageInfoState.Skip += itemCount;

    isCancelled = IsCancelled(asyncOp.UserSuppliedState);

} while (!isCancelled

    && request.PageInfoState.IsFullPage(itemCount));

Using the PagedRequestManager
Using the paged request manager is simple. In this example we create a Form-level PagedRequestManager object.

_pageRequestManager = new PagedRequestManager();

_pageRequestManager.ExecutePagedRequestAsyncCompleted += new EventHandler<ExecutePagedRequestAsyncCompletedEventArgs>(_pageRequestManager_ExecutePagedRequestAsyncCompleted);

When the Load Async button is clicked, we cancel any active requests, rebind our list, and execute a new request.

private void LoadWCFAsync_Click( object sender, RoutedEventArgs e)

{

    // Cancel any pending requests

    _pageRequestManager.CancelAsync(_searchTaskId);

 

    // Initialize and bind our ObservableCollection

    _fo odItems = new ObservableCollection<Food>();

    ((ObservableCollection<Food>)_foodItems).CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Window1_CollectionChanged);

    FoodList.ItemsSource = _foodItems;

 

    // Begin a new request

    _searchTaskId = new object();

    StartFirstResultTimer();

    _pageRequestManager.ExecutePagedRequestAsync(

        new GetAllFoodsRequest(new PagingContext() { Skip = 0, Take = 100 })

        , _foodItems, _searchTaskId);

}

Because the PagedRequestManager accepts any IPagedRequest object we can use this exact same pattern to execute a text search.

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)

{

    // Cancel any pending requests

    _pageRequestManager.CancelAsync(_searchTaskId);

 

    // Initialize and bind our ObservableCollection

    _foodItems = new ObservableCollection<Food>();

    FoodList.ItemsSource = _foodItems;

 

    // Begin a new request

    string partialDesc = ((TextBox)sender).Text;

    if (!string.IsNullOrEmpty(partialDesc))

    {

        SearchForFoodRequest request = new SearchForFoodRequest()

        {

            PageInfo = new PagingContext() { Skip = 0, Take = 100 },

            PartialDescription = partialDesc

        };

 

        _searchTaskId = new object();

        _pageRequestManager.ExecutePagedRequestAsync(request, _foodItems, _searchTaskId);

    }

}

About time... 
This has been a lengthy example, but hopefully it illustrates that a little planning upfront can go a long way for improving the end user experience for your application. User’s no longer expect to click and wait – they want instant results or at least a responsive application while they wait for results.

The patterns shown in this series of posts make consuming large lists of data a manageable task. On my local machine, retrieving 7539 food objects synchronously took 0.7 seconds. When paged asynchronously, 100 objects per page, the first 100 results were displayed and useable in 0.03 seconds with the 7539th object displayed 1.6 seconds after the button was clicked. Although the time to display the last object took more that twice as long when paged, the first 100 objects were displayed 23 times faster. These numbers become even more revealing when consuming the service over a network or the internet.

I hope that this series of posts was useful to you and your projects. The source code can be downloaded here.

Tags:

WCF | WPF

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About the author

Chad

Meeeee!!!

Hi, my name is Chad Boschert and I'm a software developer in Springfield, Missouri. I've been developing .NET applications in C# since 2002.

Recent Comments

Comment RSS

Calendar

<<  May 2013  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar