由于 DelegateCommand 而导致 WPF 应用程序内存泄漏

2024-02-14

我刚刚使用 MVVM 模式完成了用 WPF 和 C# 编写的桌面应用程序。在此应用程序中,我使用 Delegate Command 实现来包装 ModelView 中公开的 ICommands 属性。问题是这些 DelegateCommands 阻止我的 ModelView 和 View 在关闭视图后被垃圾收集。所以它会一直保持活跃状态​​,直到我终止整个应用程序。我对应用程序进行了概要分析,发现它完全与将模型视图保留在内存中的委托命令有关。 我怎样才能避免这种情况,这是 mvvm 模式的本质,还是我植入了该模式?谢谢。

编辑:这是我如何实现 MVVM 模式的小但完整的部分

第一:CommandDelete类

class DelegateCommand:ICommand
{
    private Action<object> execute;
    private Predicate<object> canExcute;
    public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }
        this.execute = execute;
        this.canExcute = canExecute;
    }
    public bool CanExecute(object parameter)
    {
        if (this.canExcute != null)
        {
            return canExcute(parameter);
        }
        return true;
    }

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


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

第二:ModelView类

public class ViewModel:DependencyObject, INotifyPropertyChanged
{
    private DelegateCommand printCommand;

    public ICommand PrintCommand
    {
        get
        {
            if (printCommand == null)
            {
                printCommand = new DelegateCommand(Print, CanExecutePrint);
            }
            return printCommand;
        }
    }
    void Print(object obj)
    {
        Console.WriteLine("Print Command");

    }
    bool CanExecutePrint(object obj)
    {
        return true;
    }


    public event PropertyChangedEventHandler PropertyChanged;
    private void OnProeprtyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

第三:窗口代码隐藏

public MainWindow()
    {
        InitializeComponent();
        base.DataContext = new ViewModel();
    }

第四:我的 XAML

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.InputBindings>
    <KeyBinding Key="P" Modifiers="Control" Command="{Binding Path=PrintCommand}"/>
</Window.InputBindings>
<StackPanel>
    <Button Content="Print - Ctrl+P" Width="75" Height="75" Command="{Binding Path=PrintCommand}"/>
</StackPanel>

就您而言,什么包含对什么的引用?

  1. DelegateCommand包含对ViewModel - its execute and canExecute属性包含对方法的引用ViewModel实例。

  2. ViewModel包含对DelegateCommand - its PrintCommand财产。

  3. 该视图包含任意数量的引用ViewModel.

  4. The CommandManager包含对DelegateCommand in its RequerySuggested event.

最后一个参考是一个特殊情况:CommandManager uses a WeakReference in its RequerySuggested事件,所以尽管事实上DelegateCommand注册该事件,它仍然可以被垃圾收集。

考虑到这一切,你应该不会有问题。如果视图被释放,则ViewModel也不DelegateCommand应该是可以到达的。

您说您已经分析了该应用程序并且DelegateCommand持有一个参考ViewModel。在我看来,合乎逻辑的下一个问题应该是:什么持有对DelegateCommand?不应该是这样CommandManager。您的应用程序中是否还有其他内容引用您的命令?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

由于 DelegateCommand 而导致 WPF 应用程序内存泄漏 的相关文章

随机推荐

  • Minhash实现如何找到排列的哈希函数

    我在实施 minhashing 时遇到问题 在纸上和阅读中我理解了这个概念 但我的问题是排列 技巧 实现的建议不是排列集合和值的矩阵 而是 选择 k 例如 100 个独立的哈希函数 然后算法表示 for each row r for eac
  • 查询 CosmosDb 非结构化 JSON

    CosmosDB 如何查询动态 JSON 中的属性值 该应用程序允许将 JSON 存储为对象的一组自定义属性 它们被序列化并存储在 CosmosDb 中 例如 这里有两个条目 id ade9f2d6 fff6 4993 8473 a2af4
  • 为什么我的图像旋转算法不起作用?

    尝试 1 和 2 Note 删除了减少问题大小的首次尝试 请参阅社区 wiki 了解之前的尝试 尝试3 根据 fuzzy waffle 的示例 我已经实现了以下内容 但它似乎无法正常工作 有什么想法我可能做错了什么吗 ImageMatrix
  • Selenium 在 JS 中使用 async/await,查找并单击元素

    我正在尝试使用 Selenium webdriver 和 Mocha 将我的测试重构为具有异步 等待功能的 ES7 我有以下代码 await loginPage loginAsAdmin THIS DOES NOT WORK await l
  • 多数据库应用程序的访问控制

    我有一个 mainDB nsf 其中包含所有 XPage 设计 代理 脚本库等 用户从该数据库中选择一个应用程序 可能存在一个或多个应用数据库 每个应用程序数据库都包含应用程序的实际数据 以及在 mainDB 中的自定义控件中访问的数据的视
  • 如何使用请求的第一个字母使用 .htaccess 重写缓存子目录?

    我有一个缓存程序 可以创建动态生成的 php 文件的静态 html 文件 我目前使用 php 来检查缓存版本是否存在 如果存在 我将其提供并退出 正如在这个问题 http stackoverflow com questions 561273
  • 如何在sklearn中实现n次重复的k折交叉验证以产生n*k折?

    I got some trouble in implementing a cross validation setting that i saw in a paper Basically it is explained in this at
  • 如何将 webpack 与 create-react-app 一起使用?

    我创建了一个创建反应应用程序 https github com facebook create react app项目遵循create react app 提供的文档 https facebook github io create reac
  • 彩色变音符号和 unicode 行为

    我只是偶然发现这个关于着色变音符号的问题 https stackoverflow com questions 23537441 how to display accents over words with different colors
  • 如何备份/移动 LXC 容器?

    我想要 lxc 容器备份 我们有服务器12 04 LTS ubuntu server我已经安装了LXC 1 0 0 alpha2在里面 我想将我们的 ubuntu 服务器更新到 14 04 LTS 所以我想做的是备份 LXC 容器 gt 将
  • Java/Swing 中的翻书

    你们都看过那些基于 Flash 的翻页书 我想用 Java 创建同样的东西 我使用 JTextArea 作为书的叶子 我想知道的是如何通过重写与 Mouse KeyListener 相结合的 componentPaint 方法来实现翻页效果
  • Perl的@INC是如何构造的? (又名影响 Perl 模块搜索位置的所有方法是什么?)

    影响 Perl 模块搜索位置的方式有哪些 或者 Perl的 INC是如何构造的 据我们所知 Perl 使用 INC包含目录名称的数组 用于确定在哪里搜索 Perl 模块文件 https stackoverflow com questions
  • 如何有条件地将服务注入组件?

    我有2个服务one service ts and two service ts 和一个组件dashboard component ts 如何有条件地将这些服务注入到组件中 import Component ViewEncapsulation
  • Linq VAR 和类型化对象

    我想要一个代码示例 目前我在 c 和 asp net 4 ef4 中使用 linq var querySlotOrder from slot in context CmsSlots where slot SlotId myCurrentSl
  • Sublime Text 的缩进错误

    我正在尝试使用 Sublime Text 3 for HTML 中的自动缩进功能 我在 html 中有一些块注释 选择 编辑 gt 行 gt 重新缩进 可以正常工作 直到遇到块注释 尝试重新缩进此处的示例 table tr td Cell
  • imagecreatefromjpeg 和类似的函数在 PHP 中不起作用

    我已经搜索过了 过去的问题中提供的解决方案对我来说完全无法理解 每当我运行类似的函数时imagecreatefromjpeg 我明白了 致命错误 调用未定义的函数 imagecreatefromjpeg 我正在安装新的 PHP 我上次安装从
  • 异步和等待 - 如何维护执行顺序?

    我实际上正在阅读一些有关任务并行库以及使用 async 和 wait 进行异步编程的主题 C 5 0 in a Nutshell 一书指出 当使用await关键字等待表达式时 编译器会将代码转换为如下所示 var awaiter expre
  • dplyr:按组查找每个 bin 的平均值

    我正在尝试理解 dplyr 我按组 箱和符号拆分数据框中的值 并且尝试获取每个组 箱 符号组合的平均值 我想输出一个数据框 其中包含每个组 箱 符号组合的这些计数以及每个组的总数 我想我有它 但有时与 ddplyr 的输出相比 我在基本 R
  • 在 Oracle PL/SQL 中,有什么方法可以导入包及其成员吗?

    给定一个包 create or replace package foo as f1 number 1 end 代替 declare begin dbms output put line f1 foo f1 end 我想写 declare b
  • 由于 DelegateCommand 而导致 WPF 应用程序内存泄漏

    我刚刚使用 MVVM 模式完成了用 WPF 和 C 编写的桌面应用程序 在此应用程序中 我使用 Delegate Command 实现来包装 ModelView 中公开的 ICommands 属性 问题是这些 DelegateCommand