MaterialDesignInXAML / MaterialDesignInXamlToolkit

Google's Material Design in XAML & WPF, for C# & VB.Net.
http://materialdesigninxaml.net
MIT License
15.18k stars 3.43k forks source link

MVVM使用SnackbarMessageQueue导致不能被GC(内存泄露) #3554

Closed daigs closed 4 months ago

daigs commented 6 months ago

Bug explanation

image image image 如上图,把SnackbarMessageQueue注入到TestGCViewModel,然后在TestGCView绑定,当关闭TestGCView时,不会触发TestGCView和TestGCViewModel的析构函数,即使手动GC,也不能触发

image 当我在TestGCView重写的OnClosed方法手动把Snackbar.MessageQueue=null释放引用后,就可以触发析构函数的执行

正常情况不是应该关闭view后,都会回收该view和对应的viewmodel的吗?

Version

5.0

daigs commented 6 months ago

image 我改成不用依赖注入,直接new,就可以触发析构函数的执行

nicolaihenriksen commented 4 months ago

@daigs I am missing a bit of context here, but my first thoughts when looking at the screenshots you provided are:

Who (i.e. what code) creates TestGCViewModel? Is it added as a transient registration in the ServiceCollection? If not that may be your issue. I believe the built-in IoC container respects the IDisposable interface and will invoke Dispose() on any registered types once they are orphaned. However, since your VM in this case has a reference to it, that won't happen unless your VM is also orphaned; so a kind of chicken and the egg problem. So in conclusion, I believe the IoC container is keeping your VM alive because it cannot dispose the SnackbarMessageQueue because your VM is holding on to it.

If your VM is also registered as transient in the ServiceCollection I think the cleanup will happen correctly.

It seems like you've "solved" your issue by simply new'ing up an instance of the SnackbarMessageQueue yourself, so I will close the issue with this comment. If you have further comments/issues feel free to re-open it.