#c# #xaml #silverlight #resources #silverlight-5.0
#c# #xaml #silverlight #Ресурсы #silverlight-5.0
Вопрос:
Я столкнулся с проблемой потребления памяти в приложении Silverlight 5.
После нескольких дней измерений я увидел, что основными потребителями памяти являются пользовательские пользовательские элементы управления (с xaml), и что эти элементы управления выделяются на фоне остальных элементов управления, которые не имеют xaml (например, унаследованные от System.Windows.Элементы управления.Текстовое поле (System.Windows.Элементы управления.Контроль)).
Я был удивлен, узнав, что при вызовах элемента управления Silverlight InitializeComponent();
(constructor) Фреймворк вызывается System.Windows.Application.LoadComponent(Object, Uri)
каждый раз, чтобы получить xaml.
Итак, если вы создаете 500 элементов управления динамически (одного и того же типа), Framework будет вызывать LoadComponent()
500 раз? Я ожидал, что xaml будет загружен только при первом создании экземпляра элемента управления, и не более LoadComponent()
после этого.
Мои вопросы:
- Можно ли включить какой-то механизм кэширования» в Silverlight, чтобы при создании экземпляра некоторого UserControl Фреймворк распознал, что xaml был загружен ранее, и чтобы не делать то же самое снова, загружает xaml только в первый раз?
- Существует ли какой-либо другой механизм или хорошая практика, позволяющие избежать загрузки одного и того же xaml каждый раз?
У меня есть базовый пример с упомянутыми типами элементов управления. Вы можете найти пример кода ниже. Это всего лишь базовый пример, без каких-либо привязок, объектов DataContext, свойств зависимостей и так далее.
Элементы управления
MyTextBox.cs, который наследуется от System.Windows.Элементы управления.Текстовое поле
using System.Windows.Controls;
namespace TestControls.Controls
{
public class МyTextBox : TextBox
{
public МyTextBox()
{
Text = "MyTextBox";
}
}
}
myText.xaml
<UserControl x:Class="TestControls.Controls.MyText"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Name="Text"/>
</Grid>
</UserControl>
myText.xaml.cs
using System.Windows.Controls;
namespace TestControls.Controls
{
public partial class MyText : UserControl
{
public MyText()
{
InitializeComponent();
Text.Text = "MyTextControl";
}
}
}
Приложение
MainPage.xaml
<UserControl x:Class="TestControlsApplication.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Name="Panel"/>
</Grid>
</UserControl>
MainPage.xaml.cs
using System.Windows.Controls;
using TestControls.Controls;
namespace TestControlsApplication
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
for (int i = 0; i < 1000; i )
{
MyText t = new MyText();
МyTextBox tb = new МyTextBox();
Panel.Children.Add(t);
Panel.Children.Add(tb);
}
}
}
}
Элемент управления myText (с xaml) выделяет 5,1 МБ (все экземпляры) и MyTextBox, который наследует System.Windows.Элементы управления.Текстовое поле выделило 0,4 МБ.
Аналогичная ситуация возникает, когда мы сравниваем время создания двух элементов управления.
Комментарии:
1. Если вы создаете элемент управления полностью в коде, ему не нужно ничего загружать. В противном случае он должен создать все элементы управления, указанные в xaml, задать их свойства и т. Д. вот почему он читает его каждый раз. Думайте о xaml как о списке задач для элемента управления. Для создания экземпляра вам нужен такой список: либо в виде кода, либо в виде xaml, верно?
2. Другой момент заключается в том, что вы создаете один и тот же элемент управления 1000 раз. Обычно у вас их не так много. Используйте элементы управления списком (
ListBox
,ListView
, и т.д.) они поддерживают виртуализацию и будут создавать элементы управления только для видимых в данный момент элементов, экономя вам много памяти и времени.3. @Sinatr: Первый вопрос: Да, это вариант — реализовать управление без xaml — полностью в коде, как вы сказали. Но я пытаюсь избежать этого (у меня более одного элемента управления с такого рода проблемами) и посмотреть, есть ли волшебная кнопка включения / выключения в SL (или WPF) для выполнения ,,кэширования» xaml. Я не нашел ответа во время своего расследования, вот почему я спрашиваю. 🙂
4. @Sinatr : Второй момент: виртуализация реализована в местах, где доступна такая презентация. В некоторых частях приложения (бизнес-приложения) пользователю должен быть представлен большой объем данных, поэтому все эти элементы управления создаются в какой-то момент. Если у меня есть большое количество элементов управления (с xaml), которые потребляют в 12-13 раз больше ресурсов, чем аналогичные элементы управления (только без xaml), виртуализация — это лишь верхушка айсберга.