我有一个小问题。我正在尝试创建一个UWP C#应用程序,我正在项目中使用切换开关。如果我经常从软件切换ToggleSwitch的状态,则内存使用量会大大增加。为什么会这样?
ToggleSwitch表示使用绑定的布尔值。
我创建了示例代码:
XAML:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ToggleSwitch Header="Test" HorizontalAlignment="Left" Margin="213,27,0,0" VerticalAlignment="Top" IsOn="{Binding Path=TestBool, Mode=TwoWay}"/>
<CheckBox Content="Two-state CheckBox" Margin="108,162,0,806" IsChecked="{Binding Path=TestBool, Mode=TwoWay}"/>
<Button Content="Start!" HorizontalAlignment="Left" Margin="69,58,0,0" VerticalAlignment="Top" Click="Button_Click"/>
</Grid>
C#:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.ComponentModel;
using System.Runtime.CompilerServices;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace App1
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
///
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
private bool testBool = false;
public bool TestBool { get { return testBool; } set { if (testBool != value) { testBool = value; OnPropertyChanged(); } } }
public MainPage()
{
DataContext = this;
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 10000; i++)
{
TestBool = !TestBool;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
我做的事情是不可能的,我理解错了什么?
当我用CheckBox替换ToggleSwitch时,内存使用量会少得多。
答案 0 :(得分:1)
您的应用程序似乎正在发生内存泄漏,这解释了GC无法释放它的原因。
一些注意事项:
为什么要在页面级别实施INotifyPropertyChanged
?您应该在单独的类上实现它。该类应该保留模型并实现ViewModel
接口本身。
该类通常被命名为IsOn
,顾名思义它包含View的模型,它知道如何将任何更改传达给它。
通常情况下,大多数内存泄漏的Bindings问题都是在使用编译绑定时发生的,{x:Bind ...},但是你正在使用传统的绑定。您已正确执行绑定到依赖项属性(例如INotifyPropertyChanged
)并且还在源对象上实现了ViewModel
,因此我不认为存在一些本质上与您如何启动约束过程。
您正在连续执行100次绑定更新,因此即使CPU使用率稍低,也可以预期在迭代循环时,您的CPU使用率会增加。 Ps:由于你没有将你的方法标记为`async,你将阻止UI线程直到你的循环操作结束,这可能是你想要改变的东西。 绑定更新肯定是一个过程,每个中间都有一些操作,这就是为什么我“有信心”CPU使用率可能不是一个大问题。
我实际上没有猜测,但我强烈建议重构您的代码以将<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Logs\Example.log"/>
<param name="Create" value="true"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="5MB"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %m%n"/>
</layout>
</appender>
<logger name="LOGGER">
<appender-ref ref="LogFileAppender"/>
</logger>
</log4net>
类实现为额外的类,并观察观察到的内存泄漏是否存在。
答案 1 :(得分:0)