简体   繁体   English

绑定到结构的属性会导致 WPF 中的 memory 泄漏吗?

[英]Can binding to a struct's property cause memory leaks in WPF?

Consider the following struct and class :考虑以下structclass

public struct DemoStruct
{
    public DemoStruct(int value)
    {
        Value = value;
    }
    
    public int Value {get; }
}


public class DemoClass : INotifyPropertyChanged
{
    private DemoStruct _demo;
    public DemoStruct Demo 
    {
        get => _demo;
        set {_demo = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Demo)); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

And, assuming the DataContext is an instance of DemoClass , consider this binding:并且,假设DataContextDemoClass的一个实例,考虑这个绑定:

<Label Content="{Binding Demo.Value}"/>

By now I've learned that binding to an object that is not a DependencyObject or does not implement INotifyPropertyChanged can cause a memory-leak, see eg Why does implementing INotifyPropertyChanged avoid memory leaks in WPF?到目前为止,我已经了解到绑定到不是DependencyObject或未实现INotifyPropertyChanged的 object 可能会导致内存泄漏,请参见例如, Why does implementing INotifyPropertyChanged avoid memory leaks in WPF? . .

What I'm wondering is how WPF will handle binding to a struct property.我想知道 WPF 将如何处理绑定到struct属性。

My DemoStruct does not implement INotifyPropertyChanged , because it is an immutable struct.我的DemoStruct没有实现INotifyPropertyChanged ,因为它是一个不可变的结构。

I'm assuming it will be boxed by WPF, but will this also create a memory leak, due to the "strong reference" to the boxed struct instance?我假设它将被 WPF 装箱,但是由于对装箱struct实例的“强引用”,这是否也会造成 memory 泄漏?

And, since a new box will be created whenever WPF accesses the property - will these all leak?而且,由于每当 WPF 访问该属性时都会创建一个新框 - 这些都会泄漏吗?

And, a follow up to be on the safe side:并且,为了安全起见,请采取后续行动:

If I were to change the binding to:如果我要将绑定更改为:

<Label Content="{Binding Demo}"/>

Despite the boxing, this should not cause a leak, because WPF does not have to attach any event handlers to "Demo" - right?尽管装箱,这不应该导致泄漏,因为 WPF 不必将任何事件处理程序附加到“Demo”——对吧?

Short answer is yes, they can do.简短的回答是肯定的,他们可以做到。 Unless you use mode=.netime bindings.除非你使用 mode=.netime 绑定。

https://learn.microsoft.com/en-us/do.net/api/system.windows.data.bindingmode?view=windowsdesktop-7.0 https://learn.microsoft.com/en-us/do.net/api/system.windows.data.bindingmode?view=windowsdesktop-7.0

The struct itself will not cause memory leaks.该结构本身不会导致 memory 泄漏。

Properties on that struct would do.该结构上的属性就可以了。

Demo is a property in a class that implements Inotifypropertychanged. Demo是class中的一个属性,实现了Inotifypropertychanged。 If you bound to Demo then that would not cause a leak but you get a struct.如果你绑定到 Demo 那么这不会导致泄漏,但你会得到一个结构。 That might not be terribly useful.这可能不是很有用。

If you bind to Demo.Value then that's a property on a struct and that will cause a hard reference to be created.如果您绑定到 Demo.Value,那么这是结构上的一个属性,这将导致创建硬引用。 Unless....除非....

Since Demo is to be immutable then maybe in your use case you could try a .netime binding.由于 Demo 是不可变的,那么也许在您的用例中您可以尝试 .netime 绑定。 That doesn't then care about any property changing.那不关心任何属性的变化。

https://learn.microsoft.com/en-gb/archive/blogs/jgoldb/finding-memory-leaks-in-wpf-based-applications https://learn.microsoft.com/en-gb/archive/blogs/jgoldb/finding-memory-leaks-in-wpf-based-applications

If you switch out Demo then you could consider a converter to read the data out value.如果您关闭 Demo,那么您可以考虑使用转换器来读取数据输出值。 Bind to Demo and use a converter which would then read Value and return that.绑定到 Demo 并使用一个转换器,该转换器将读取 Value 并返回它。 Might be a bit clunky if you had more than one property.如果您拥有不止一处财产,可能会有点笨拙。

You could alternatively wrap Demo.Value with another property in your viewmodel.您也可以在视图模型中用另一个属性包装 Demo.Value。 Raise propertychanged on wrapper property when demo changes.当演示更改时,在包装器属性上提高 propertychanged。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM