Time increases to update private Observable Collection with each refresh

I have a WPF application using MVVM approach.

In one of my viewmodels I have a private observable collection which I set to a 'new observableCollection' which is created from a query which fetches the data via a repository class using an ISession object from NHibernate.

I have a private observable collection in my viewmodel which I want to update with the collection returned/created from my query.

The problem is, every time I call my method to perform the query, the time taken to update the private object ( ObservableCollection ) takes longer every time.

I tested the time taken for the query to execute in the repository and its only 4 or 5 seconds.. I am retrieving 4500 records using lazy loading.

So my question is why would the time increase every time I call my refresh method in the viewmodel? Additionally I should also add that the memory usage shown in task manager also increases so it almost appears there is a memory leak?

Code example below:

ViewModel:

private static ObservableCollection<CustomerViewModel> _allCustomers;      
Expression<Func<Customer, bool>> expression2 = p => p.IsVisible == 'T';

_allCustomers = new ObservableCollection<CustomerViewModel>(
    from customer in ManyEntitiesRepository<Customer>.Instance.RetrieveAll(expression2)
    select new CustomerViewModel(customer));

Repository Retrieve

    public virtual IList<T> RetrieveAll(Expression<Func<T, bool>> expression)
    {
        try
        {
            if (_allEntities != null)
            {
                foreach (T entity in _allEntities)
                    SessionProvider.Instance.GlobalSession.Evict(entity);
                _allEntities.Clear();
            }

            _allEntities = (from c in SessionProvider.Instance.GlobalSession.Query<T>().AsExpandable()
                            where expression.Invoke(c)
                            select c).ToList<T>();

            return _allEntities;
        }

Answers


Ok so as mentioned before, the viewmodels were doubling in size. When the application first loads it loaded 4689 records from the database. With every refresh done to retrieve a fresh set of data from the database there were another 4689 loaded and so on... and so on. This was pretty massive in terms of memory leakage.

The reason for this happening was I had 2 messages registered in the viewmodel I was creating a collection of where those messages were referencing other viewmodels. The messages although do show up as 'Weak References' when I traced them in Ants Memory profiler but were not releasing the other objects.

Once I delete the 2 references there was no issues. Fast retrieval of data and no memory leak.

Messenger.Default.Register<BroadcastPropertyChanged<ControlContainerTemplate>>(this, (message) =>
        {
            //// Instance needs to find out if it is a real receiver
            if (_udfViewModel != null && _udfViewModel.ControlsValue.Any((c) => message.Sender == c))
                RaiseBooleanFlagsChanged();
        });

        Messenger.Default.Register<BroadcastPropertyChanged<ChargeTemplateViewModel>>(this, (message) =>
            {
                //// Instance needs to find out if it is a real receiver
                if (_chargeTemplates != null && _chargeTemplates.Any((c) => message.Sender == c))
                    RaiseBooleanFlagsChanged();
});

I am using the Galasoft.MVVM Light Toolkit... where it states that the messages dont need disposed as they are weak references but now I am obviously going to have to look for an alternative to have my viewmodels communicate, or am going to have to see how to unregister those messages before creating a new collection of that viewmodel.

On checking out :http://mvvmlight.codeplex.com/ , Laurant has identified this problem which I am only seeing now :) but he is looking to fix this issue in MVVM Light toolkit in version 4 so as that the weak reference actually is a weak reference and the viewmodels can be released and collected by the GC.

Thanks


To workaround this I am looping the viewmodels in my private collection and calling cleanup() on each... adds an extra 4 seconds or so to the refresh but hey its better than having your memory clogged up with duplicate viewmodels and having the query time increase by 20 seconds or more with each refresh.

                    foreach (XViewModel m in _xCollection)
                    {
                        m.Cleanup();

                     }

I will keep an eye out for V.4 of the toolkit release in the coming months...

Cheers


Need Your Help

How do I get slot number for texture by name?

sharpdx direct3d11

Using Direct3D 11 and SharpDX, given the name of a Texture Map as declared in the shader, how do I know what slot to assign my Sampler and TextureView to?

TreeView ScrollBar bug

c# winforms

I have a treeview in the winform application....

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.