How can I remove those retentions?

Hello,

I've a WPF application that uses Catel as MVVM Framework. I've seen that a viewmodel doesn't get collected since it has 2 references to a CanExecuteChanged EventHandler I don't expose myself

 

Those commands are added via behavior to a grid in order to perform action on context menu and the code I use is

<pre>

protected virtual IEnumerable<RadMenuItem> GetRowMenuItems(RadContextMenu contextMenu)
{
var rowItems = new List<RadMenuItem>();

RadMenuItem saveSettings = new RadMenuItem
{
Tag = "force",
Header = CoreResources.LBL_SAVE_SETTINGS,
Command = DefaultRtViewContextMenuCommands.SaveLayoutDataCommand,
CommandParameter = AssociatedObject,

Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/IF.Tesoreria.Client.WPF.Core;component/Media/save.png")) }
};

rowItems.Add(saveSettings);

RadMenuItem loadSettings = new RadMenuItem
{
Tag = "force",
Header = CoreResources.LBL_LOAD_SETTINGS,
Command = DefaultRtViewContextMenuCommands.LoadLayoutDataCommand,
CommandParameter = AssociatedObject,
Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/IF.Tesoreria.Client.WPF.Core;component/Media/load.png")) }
};

rowItems.Add(loadSettings);

</pre>

Why this cause a leak?

Thanks in advance

 

 

6 comments
Comment actions Permalink

Hi Paolo,

There is not enough information to determine exactly why this issue occurs.

Probably it can be related to listener which are never unsubscribed from the event:

https://www.jetbrains.com/help/dotmemory/Inspections.html?Wave=7#event_handlers_leak

Also please read this answer, it can help in your case:

http://stackoverflow.com/a/12945325/7140949

Pay your attention on INotifyPropertyChanged implementation in your view model (it's also described in answer I mentioned above).

If these suggestions don't help you, could you please provide us solution sample? You can upload it to our FTP server: ftp://ftp.intellij.net/.uploads/ (anonymous login, .uploads directory has no permissions to list/download files, only for upload, so other users will not be able to download your files).

 

 

0
Comment actions Permalink

Hello,

I've created a sample project

 

https://drive.google.com/file/d/0B6nPFuIuKHG1eVBIa3pWRThPcUU/view?usp=sharing

 

just:

  • execute it
  • click on popup
  • right click on textblock
  • close the popup and search for  PopUpViewModel inside dotMemory
  • you'll see the holding reference.

If you comment inside the TextBoxBehavior.cs file 

 

private void OnMenuItemLoaded(object sender, RoutedEventArgs e)
{
try
{
var contextMenu2 = new RadContextMenu();

var items = GetRowMenuItems();

contextMenu2.ItemsSource = items; //<-------this (line #40)

RadContextMenu.SetContextMenu(AssociatedObject, contextMenu2);
}
catch (Exception exception)
{
Console.WriteLine(exception);

}
}

 

you'll get no more memory leak.

 

Thanks

0
Comment actions Permalink

Excuse me , I've got no feedback about this....any suggestion?

0
Comment actions Permalink

Paolo,

Sorry for delay. We need some time to explore your solution. We'll give you an answer as soon as possible.

0
Comment actions Permalink

Paolo,

The issue occurs in the Telerik's RadMenuItem control.
It doesn't unsubscribe from Command.CanExecuteChanged.
As the simplest workaround please try the following code:

    public class RadMenuItem2 : RadMenuItem
    {
        public RadMenuItem2()
        {
            Unloaded += delegate { SetValue(CommandProperty, null); };
        }
    }

But for production usage please contact Telerik for a better fix.

Besides that, change List<RadMenuItem> to ObservableCollection<RadMenuItem> in TextBoxBehavior.GetRowMenuItems() in your sample app. List doesn't implement INotifyPropertyChanged and it causes another leak.

0
Comment actions Permalink

Hello,

I've forwarded your analisys to Telerik , give you a feedback as soon as I'll have one,

Thanks!

0

Please sign in to leave a comment.