저는 LINQ to SQL을 사용하여 SQL Server 데이터베이스에 연결하는 WPF 응용 프로그램을 작성하고 있습니다.WPF 응용 프로그램에서 UI 메모리 누수가 발생하는 ICommand 바인딩
앱의 기본 창에 일련의 상세보기가 포함 된 ListView
이 있습니다. ListView
의 ItemSource
은 루트보기 모델에서 속성으로 표시되는 상세보기 모델 개체 모음에 바인딩됩니다. 각 상세보기 모델 객체는 여러 개의 ICommand
속성과 상세 모델 객체를 노출하는 속성을 구성하며 세부적인 객체는 UI에 표시된 다양한 데이터 필드를 노출합니다.
ANTS 메모리 프로파일 러를 사용한 분석 결과, 누설 된 개체가 상세 모델 개체에 포함 된 개체와 바인딩되는 일부 UI 클래스임을 알 수 있습니다. 이전의 새로 고침에서 이러한 개체의 인스턴스가 가비지 수집되지 않습니다.
ANTS에는 원치 않는 메모리가 유지되는 이유를 식별하기 위해 사용자가 참조 체인을 추적 할 수있는 도구가 있습니다. 그것을 사용할 때 나타나는 모든 체인은 ICommand
입니다. 따라서 문제가되는 ICommand
을 제거한 결과 메모리 누수가 사라지는 것을 발견했습니다.
불행히도 중요한 기능을 구현하려면 ICommand
이 필요합니다. 실제로 나를 혼란스럽게하는 것은 세부 뷰 모델 객체에서 두 개의 완전히 별개의 인스턴스 변수 인, 상세 모델 객체에 대한 참조를 처음부터 어떻게 가지는지입니다.
다음은 자세히보기 모델 개체의 생성자입니다 (RootViewModel에 대한 참조는 ICommands에 연결된 일부 메서드의 콜백에 사용됩니다.) 원래는 이것이 참조의 순환 체인을 일으킬 수 있다고 생각했습니다. .을 제거하여 문제의 원인, 그러나 어떤 영향을하지 않는 것)
public CarDataViewModel(CarData carDataItem, RootViewModel parentViewModel)
{
_parentViewModel = parentViewModel;
CarDataModel = carDataItem;
CompetingCheckboxStatus = CarDataModel.CurrentCar.Competing;
AcknowledgeAlarm = new ParameterlessCommand(AcknowledgeAlarmClicked);
Acknowledge = new ParameterlessCommand(AcknowledgeClicked);
ShowReport = new ParameterlessCommand(ShowReportClicked);
Cancel = new ParameterlessCommand(CancelClicked);
}
여기 바인딩이 설정되어있는 XAML의 - AcknowledgeAlarm는 ICommand의이다, CarDataModel는 세부 모델 객체는 다음과 같습니다
<ListView x:Name="itemGridView"Grid.Row="1"ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding CarDataViewModels}" IsSynchronizedWithCurrentItem="True" Margin="0,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
</DataTemplate.Resources>
<Button Command="{Binding AcknowledgeAlarm}">
<Border DataContext="{Binding CarDataModel}" BorderBrush="{StaticResource GrayFadeBrush}" Background="White" BorderThickness="5">
<Grid> . . .
이것이 ParameterlessCommand의 CanExecuteChanged 이벤트와 관련이 있다고 생각됩니다. 어떻게 구현되는지 보여줄 수 있습니까? – Daniel
그것은'의 공개 이벤트 핸들러 CanExecuteChanged은,''보호 된 가상 무효가 (있는 EventArgs 인수) { OnCanExecuteChanged 경우 (CanExecuteChanged = 널!) { CanExecuteChanged (이, 인수); } }'- 서식을 사용하여 죄송합니다. 반환 할 수없는 것으로 보입니다. –