ReactiveUI ViewModel 内存泄漏

ReactiveUI ViewModel memory leak

我在内存泄漏方面遇到了非常奇怪的问题,经过长时间的测试、调试和 trial/error 尝试后我找不到源代码。

内存泄漏的根源是根据主题的推送重新加载对象。我在哪一部分加载当前数据库值并将其添加到 SourceCache。

这部分正在获取推送,以启动重新加载

this.databaseSignalRClient
                .UpdatedObservable<JobLine>()
                .WhereNotNull()
                .Where(x => JobLinesCache.Lookup(x.Id).HasValue)
                .SelectMany(LoadJobLine)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(jl => JobLinesCache.AddOrUpdate(jl));

这里有 LoadJobLine 函数

        private async Task<JobLine> LoadJobLine(DbNotification dbNotification)
        {
            using var repo = Locator.Current.GetService<IWmsRepository>();
            return await repo.Job.JobLineRepository.FindAsync(dbNotification.Id);
        }

这就是我向 UI 提供 ViewModels 的方式:

        private readonly ReadOnlyObservableCollection<JobLineViewModel> jobLineViewModels;
        public ReadOnlyObservableCollection<JobLineViewModel> JobLineViewModels => jobLineViewModels;
            JobLinesCache.Connect()
            .SortBy(jl => jl.CaseNo)
            .Transform(jl => new JobLineViewModel(jl))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Bind(out jobLineViewModels)
            .Subscribe();

这是创建的 ViewModel:

    public class JobLineViewModel : ReactiveObject
    {

        public JobLineViewModel(
            JobLine jobLine
            )
        {
            JobLine = jobLine;
        }


        [Reactive]
        public JobLine JobLine { get; private set; }

        [Reactive]
        public string ContainingItemsString { get; private set; }
    }

最后将集合绑定到 UI:

            this.WhenActivated(d =>
            {
                this.OneWayBind(ViewModel, vm => vm.JobLineViewModels, v => v.TestIC.ItemsSource)
                .DisposeWith(d);
            });

我确实测试了虚拟化堆栈面板和没有。

            <ItemsControl x:Name="TestIC">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>

还有这个问题。 JobLineViewModel 由于某种原因没有得到垃圾收集。我通过每 10 毫秒 ping 一次 signalR 更新来模拟它。

我真的不知道是什么让 JobLineView 保持活力。我也可以 post 它的代码,但我没有看到任何问题...:[=​​26=]

<rx:ReactiveUserControl x:Class="Mtc.UserControls.JobLineView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Mtc.UserControls"
             mc:Ignorable="d" 
                              x:TypeArguments="vm:JobLineViewModel"
             xmlns:rx="http://reactiveui.net"
                        xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:vm="clr-namespace:Wms.Mtc.ViewModels;assembly=Wms.Mtc"
             d:DesignHeight="450" d:DesignWidth="800">
 
        <md:Card Margin="20,10">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />
            </Grid.RowDefinitions>

            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="auto" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Viewbox Margin="10">
                    <TextBlock x:Name="CaseNo_TextBlock" VerticalAlignment="Center" HorizontalAlignment="Center" />
                </Viewbox>
                <Grid Margin="10" Grid.Column="1">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="auto" />
                        <RowDefinition Height="auto" />
                        <RowDefinition Height="auto" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="D01 D01-020-0B-21" Grid.Row="0" HorizontalAlignment="Center" />
                    <!--<md:PackIcon Kind="ArrowBottom" Grid.Row="1" HorizontalAlignment="Center" Width="45" Height="45" />-->
                    <TextBlock Text="D09" Grid.Row="2" HorizontalAlignment="Center" />
                </Grid>
            </Grid>
            <TextBlock x:Name="Items_TextBlock" FontSize="28" HorizontalAlignment="Center" Margin="5" Grid.Row="1" />
        </Grid>
        </md:Card>
</rx:ReactiveUserControl>

和后面的代码:

    public partial class JobLineView : ReactiveUserControl<JobLineViewModel>
    {
        public JobLineView()
        {
            InitializeComponent();
            this.WhenActivated(d =>
            {
                this.OneWayBind(ViewModel, vm => vm.JobLine, v => v.CaseNo_TextBlock.Text, jl=>jl.CaseNo)
                .DisposeWith(d);

         /*       this.OneWayBind(ViewModel, vm => vm.JobLine.Status, v => v.CaseNo_TextBlock.Foreground, status=> JobLineStatusToBrushConverter.Instance.Convert(status,null,null,null))
                .DisposeWith(d);

                this.OneWayBind(ViewModel, vm => vm.JobLine, v => v.Items_TextBlock.Text, jl=> JobLineToItemsStringConverter.Instance.Convert(jl, null,null,null))
                .DisposeWith(d);*/
            });
        }
    }

如有任何想法,我将不胜感激。这个真的很棘手,我不知道怎么解决。

我还添加了托管内存的屏幕截图:

谢谢

-----编辑

我确实剥离了所有内容的整个视图,以避免 MaterialDesign 中的潜在问题:

但问题仍然存在,一定是 Reactive 的问题UI,但是...

这也是 JobLine class,正在传递给 VM:

    public class JobLine : ReactiveObject
    {
        [Reactive]
        public string CaseNo { get; set; }
        [Reactive]
        public decimal? CreatedBy { get; set; }
        [Reactive]
        public DateTime? CreatedDate { get; set; }
        [Reactive]
        public string FromInventory { get; set; }
        [Reactive]
        public string FromLocator { get; set; }
        [Reactive]
        public decimal Id { get; set; }
        [Reactive]
        public decimal? JobHeaderId { get; set; }
        [Reactive]
        public decimal? MachineId { get; set; }
        [Reactive]
        public decimal? PickingOrder { get; set; }
        [Reactive]
        public decimal? Printed { get; set; }
        [Reactive]
        public decimal? RoutingId { get; set; }
        [Reactive]
        public decimal? SourceLineId { get; set; }
        [Reactive]
        public decimal? Status { get; set; }
        [Reactive]
        public string ToInventory { get; set; }
        [Reactive]
        public string ToLocator { get; set; }
        [Reactive]
        public decimal? UpdatedBy { get; set; }
        [Reactive]
        public DateTime? UpdatedDate { get; set; }
        [Reactive]
        public decimal? Valid { get; set; }
        [Reactive]
        public string WindowsUser { get; set; }
    }

在消除所有可能的因素后(剥离视图和视图模型中的任何绑定,或 material 设计内容(图标)等)问题仍然存在。某些东西与 ViewModel 一起使 View 在内存中保持活动状态。虽然不再在视觉树中。

欢迎提出任何想法。

错误已在库存储库中报告并修复: https://github.com/reactiveui/ReactiveUI/issues/3091