Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 修复RelayCommand中可能的内存泄漏_C#_Wpf_Memory Leaks_Prism - Fatal编程技术网

C# 修复RelayCommand中可能的内存泄漏

C# 修复RelayCommand中可能的内存泄漏,c#,wpf,memory-leaks,prism,C#,Wpf,Memory Leaks,Prism,使用内存探查器并比较快照,我们发现有150多个RelayCommand类型的对象在快照之间存活,而不是被释放 在快照之间先注册,然后取消注册RelayCommand 注销过程是否完成 是否有其他与要发布的RelayCommand相关的资源 中继命令代码: public class RelayCommand : ICommand { #region Fields readonly Action<object> _execute; readonly Predic

使用内存探查器并比较快照,我们发现有150多个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
}
公共类RelayCommand:ICommand
{
#区域字段
只读操作_执行;
只读谓词_canExecute;
#endregion//字段
#区域构造函数
/// 
///创建始终可以执行的新命令。
/// 
///执行逻辑。
公共中继命令(操作执行)
:此(执行,空)
{
}
/// 
///创建一个新命令。
/// 
///执行逻辑。
///执行状态逻辑。
公共RelayCommand(操作执行,谓词canExecute)
{
if(execute==null)
抛出新的ArgumentNullException(“执行”);
_执行=执行;
_canExecute=canExecute;
}
#endregion//构造函数
#区域ICommand成员
[调试步骤至]
公共布尔CanExecute(对象参数)
{
返回_canExecute==null?true:_canExecute(参数);
}
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
public void Execute(对象参数)
{
此._执行(参数);
}
#endregion//ICommand成员
}

RequerySuggested包含一个弱引用,不会阻止对象被释放,因此它不是问题的根源。如果内存影响不可接受,请尽量减少创建的命令实例数。

DelegateCommand和CompositeCommand的PRISM实现具有“私有列表”\u CanExecuteChangedHandler;”。在这种情况下需要这样做吗?确实需要这样做,但是当没有更多的强引用时,允许命令的订阅者被释放。同样,您的实现没有问题。GC释放未使用的命令之前会有一些自然延迟。影响有多大?它不应该消耗太多内存-RelayCommand很小。