gpt4 book ai didi

c# - ReactiveUI ViewModel 内存泄漏

转载 作者:行者123 更新时间:2023-12-05 05:52:49 25 4
gpt4 key购买 nike

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

内存泄漏的根源是根据主题的推送重新加载对象。我在哪一部分加载当前数据库值并将其添加到 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 提供 ViewModel 的方式:

        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; }
}

最后将集合绑定(bind)到 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 更新来模拟它。

enter image description here enter image description here

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

<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);*/
});
}
}

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

我还添加了托管内存的屏幕截图: enter image description here

谢谢

-----编辑

我确实剥离了所有内容的整个 View ,以避免 MaterialDesign 中的潜在问题: enter image description here enter image description here

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

这也是传递给 VM 的 JobLine 类:

    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; }
}

在消除所有可能的因素后(去除 View 和 View 模型中的任何绑定(bind)、 Material 设计 Material (图标)等),问题仍然存在。某些东西与 ViewModel 一起使 View 在内存中保持事件状态。虽然不再在视觉树中。 enter image description here

欢迎提出任何想法。

最佳答案

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

关于c# - ReactiveUI ViewModel 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70038308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com