修复RelayCommand中可能的内存泄漏

时间:2014-11-27 15:26:14

标签: c# wpf memory-leaks prism

使用内存分析器并比较快照,我们发现150多个类型为RelayCommand的对象在快照之间存活而不是被释放。

RelayCommand已注册,然后在快照之间取消注册。

取消注册过程是否完成?

是否还有与RelayCommand相关的其他资源?

RelayCommand代码:

public class RelayCommand : ICommand
{
    #region Fields

    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    #endregion // Fields

    #region Constructors

    /// <summary>
    /// Creates a new command that can always execute.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion // Constructors

    #region ICommand Members

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        this._execute(parameter);
    }

    #endregion // ICommand Members
}

1 个答案:

答案 0 :(得分:1)

RequerySuggested拥有弱引用并且不会阻止对象被释放,因此它不是您的问题的根源。如果内存影响不可接受,请尝试最小化创建的命令实例数。