UWP C#中的ToggleSwitch

时间:2018-04-06 11:27:52

标签: c# xaml uwp

我有一个小问题。我正在尝试创建一个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时,内存使用量会少得多。

Memory Usage

2 个答案:

答案 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)

看起来你的调用正在耗尽CPU。

enter image description here

我的回答是你应该再考虑一下你的应用程序架构。