c# - 在这种情况下,垃圾收集器是否回收了该对象?

标签 c# .net wpf mvvm

我有一个包含这段代码的主要方法:

List<MyType> myList = openDialog();

调用 openDialog 会打开一个对话框,该对话框返回一个包含所选项目的列表,该对话框用于选择项目。

private List<MyType> openDialog()
{
    MyView myView = new MyView();
    MyViewModel myViewModel = new MyViewModel();
    myView.DataContext = myViewModel;
    myView.ShowDialog();

    return myViewModel.Result;        
}

myViewModel.Result 是一个集合,其中包含 View 中数据网格的选定项。

我的问题是,我如何返回 ViewModel 的 Result 属性,我不确定 myViewModel 是否会被垃圾收集器回收,因为它仍然有对它的引用。

为了避免这种情况,我这样做:

private List<MyType> openDialog()
{
    MyView myView = new MyView();
    MyViewModel myViewModel = new MyViewModel();
    myView.DataContext = myViewModel;
    myView.ShowDialog();

    return new List<MyType>(myViewModel.Result);        
}

在返回中,我正在创建一个新列表以避免引用 Result 属性并确保重新收集 myViewModel 对象,但我想知道是否有办法避免创建新列表。

最佳答案

您还没有发布 MyViewModel 的实现但是List<MyType>从 View 模型返回不会阻止 View 模型被垃圾收集。您可以使用 WeakReference 自行确认这一点:

private void Test(object sender, RoutedEventArgs e)
{
    Window myView = new Window();
    MyViewModel myViewModel = new MyViewModel();
    myView.DataContext = myViewModel;
    myView.ShowDialog();

    List<MyType> result = myViewModel.Result;

    WeakReference viewModelWeakReference = new WeakReference(myViewModel);
    myView.DataContext = null;
    myViewModel = null;

    GC.Collect();
    GC.WaitForPendingFinalizers();

    bool isViewModelAlive = viewModelWeakReference.IsAlive; //=false
}
...
public class MyViewModel
{
    public List<MyType> Result { get; } = new List<MyType>() { new MyType(), new MyType() };
}

isViewModelAlivefalseresult.Count2运行上面的示例代码时,即 View 模型已被收集但是 List<MyType>留在内存中。

请注意 WeakReference.IsAlive将返回 true当您持有对执行 GC 测试的方法的强引用时:

List<MyType> _result;
private void Button_Click(object sender, RoutedEventArgs e)
{
    _result = openDialog();
}

private List<MyType> openDialog()
{
    Window myView = new Window();
    MyViewModel myViewModel = new MyViewModel();
    myView.DataContext = myViewModel;
    myView.ShowDialog();

    List<MyType> result = myViewModel.Result;

    WeakReference viewModelWeakReference = new WeakReference(myViewModel);
    myView.DataContext = null;
    myViewModel = null;

    GC.Collect();
    GC.WaitForPendingFinalizers();

    bool isViewModelAlive = viewModelWeakReference.IsAlive;

    return result;
}

但是myViewModel方法返回后仍然有资格进行垃圾收集,因为它没有 GC 根。

所以不需要再创建一个List<MyType>在这里。

关于c# - 在这种情况下,垃圾收集器是否回收了该对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50549988/

相关文章:

c# - 使用路径获取 Xelement.elements()

c# - OData 客户端只按顺序返回最后一个条目?

c# - .Net/C# 客户端应用程序的 WITSML api 库?

c# - 将剪贴板内容设置为自定义数据

wpf - 多线程 wpf 窗口中的 Printdialog 抛出 TargetInvocationException

c# - 如何在 Windows 中检索任何给定文件类型的默认图标?

c# - 如何在C#中正确从SqlDataReader读取数据?

c# - 动态状态机的更多 .net 方法

.net - ODP.NET TNS :no listener

wpf - 为什么无法在组合框中选择空值?