Категории
Самые читаемые
onlinekniga.com » Компьютеры и Интернет » Программирование » Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре

Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре

Читать онлайн Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 60 61 62 63 64 65 66 67 68 ... 206
Перейти на страницу:

■ Возможность иметь различные реализации для различных классов устройств. Если ваши целевые устройства охватывают несколько различных классов, то вы имеете возможность настроить ограничения на использование памяти и накопителей для каждого из этих классов по отдельности. Мобильный телефон и устройство PDA могут иметь различные характеристики памяти и различные возможности в отношении загрузки данных по требованию. Отмеченные различия могут потребовать от вас использования различных подходов к кэшированию данных. Концентрация соответствующей управляющей логики в одном месте существенно упрощает эту задачу. 

Использование модели загрузки данных по требованию

Для размещения объектов в памяти существуют две стратегии:

1. При вхождении приложения в новое состояние создаются все объекты, которые требуются для этого состояния. Достоинством этой стратегии является ее простота. Когда приложение переходит в новое состояние, вы просто вызываете функцию, которая и обеспечивает доступность и возможность использования всех необходимых объектов. Эта стратегия очень хорошо работает в тех случаях, когда имеется уверенность в том, что в ближайшее время приложению потребуются все созданные объекты. Возможные проблемы связаны с тем, что если ваше приложение находится в стадии становления и в его проект могут вноситься изменения, то применение указанной стратегии может привести к хранению в памяти большого количества ненужных объектов. Поскольку старые объекты, необходимости в которых больше нет, все равно создаются и загружаются в память, то драгоценные ресурсы тратятся понапрасну. Будьте внимательны при групповом создании наборов объектов, ибо в процессе выполнения вашего приложения может наступить такой момент, когда создаваемые объекты не используются, но связанные с ними накладные расходы ухудшают производительность.

2. Создание любого объекта откладывается до тех пор, пока необходимость в его создании не станет очевидной. Эта модель немного сложнее в проектировании, но зато во многих случаях оказывается более эффективной, поскольку объекты создаются лишь тогда, когда в них возникает действительная необходимость. При обсуждении этой модели часто употребляются такие выражения, как "фабрика классов" ("class factory"), "диспетчер ресурсов" ("resource dispenser") и "отложенная загрузка" ("lazy loading").

Приведенный в листинге 8.1 пример кода иллюстрирует два способа отложенного создания и кэширования глобально используемых графических ресурсов. Существует два способа создания объектов:

1. Пакетное создание групповых ресурсов. Приведенный ниже код создает списочный массив, содержащий четыре растровых изображения. Эти изображения являются кадрами анимации, поэтому они загружаются все вместе и помещаются в индексированный массив, откуда их можно легко извлекать. Программный код, которому требуется доступ к этой коллекции изображений, должен использовать вызов GraphicsGlobals.PlayerBitmapsCollection();. Если массив изображений уже загружен в память, функция незамедлительно возвращает кэшированный объект. В противном случае отдельные ресурсы изображений сначала загружаются в массив и лишь затем возвращаются. Если приложение переходит в состояние, в котором пребывание изображений в памяти не требуются, код приложения может выполнить вызов GraphicsGlobals.g_PlayerBitmapsCollection_CleanUp();, в результате чего произойдет освобождение растровых ресурсов и массива. Системные ресурсы, задействованные для обслуживания растровых изображений, будут немедленно освобождены, а управляемая память, которую занимали эти объекты, будет соответствующим образом восстановлена в процессе сборки мусора.

2. Индивидуальное создание графических ресурсов. В случае ресурсов, которые не должны обязательно использоваться вместе, как в приведенном выше примере, часто оказывается удобным создать функцию кэшированного доступа, посредством которой и реализуется управление доступом к ресурсу. Когда происходит первое обращение к этой функции с запросом ресурса (например, GraphicsGlobals.g_GetBlackPen();), она создает его экземпляр. В случае часто используемых ресурсов такой подход оказывается намного более эффективным, чем постоянное создание и уничтожение экземпляров ресурса всякий раз, когда он требуется для выполнения того или иного фрагмента кода. Создавая приведенный ниже код, я допустил, что все ресурсы должны освобождаться одновременно, и написал функцию (GraphicsGlobals.g_CleanUpDrawingResources();), которая освобождает все кэшированные ресурсы, которые были созданы. Эта функция должна вызываться тогда, когда приложение переходит в состояние, в котором эти ресурсы не требуются.

Используя кэширование, руководствуйтесь здравым смыслом

Если предполагается многократное использование одних и тех же ресурсов внутри функции, то вызов функции (или свойства) кэшированного доступа всякий раз, когда требуется данный ресурс, является неэффективным. В подобных случаях лучше вызвать эту функцию один раз и хранить ресурс в локальной переменной в течение всего времени, пока в данном ресурсе будет существовать необходимость. Тем самым вы получаете выигрыш от того, что используете глобально кэшированный ресурс, а не создаете и уничтожаете ресурс внутри функции, и повышаете эффективность вычислений, поскольку избавляетесь от лишних вызовов функции в своем алгоритме. Здравый смысл подскажет вам, когда такой подход является оправданным.

Листинг 8.1. Применение отложенной загрузки, кэширования и освобождения графических ресурсов 

using system;

public class GraphicsGlobals {

 private static System.Drawing.Bitmap s_Player_Bitmap1;

 private static System.Drawing.Bitmap s_Player_Bitmap2;

 private static System.Drawing.Bitmap s_Player_Bitmap3;

 private static System.Drawing.Bitmap s_Player_Bitmap4;

 private static System.Collections.ArrayList s_colPlayerBitmaps;

 //------------------------------------------------------

 //Освободить все ресурсы

 //------------------------------------------------------

 public static void g_PlayerBitmapsCollection_CleanUp() {

  //Если не загружено ни одно изображение, то и память освобождать не от чего

  if (s_colPlayerBitmaps == null) {

   return;

  }

  //Дать указание каждому из этих объектов освободить

  //любые удерживаемые ими неуправляемые ресурсы

  s_Player_Bitmap1.Dispose();

  s_Player_Bitmap2.Dispose();

  s_Player_Bitmap3.Dispose();

  s_Player_Bitmap4.Dispose();

  //Обнулить каждую из этих переменных, чтобы им не соответствовали

  //никакие объекты в памяти

  s_Player_Bitmap1 = null;

  s_Player_Bitmap2 = null;

  s_Player_Bitmap3 = null;

  s_Player_Bitmap4 = null;

  //Избавиться от массива

  s_colPlayerBitmaps = null;

 }

 //Функция: возвращает коллекцию изображений

 public static System.Collections.ArrayList g_PlayerBitmapsCollection() {

  //---------------------------------------------------------------

  //Если изображения уже загружены, их достаточно только возвратить

  //---------------------------------------------------------------

  if (s_colPlayerBitmaps != null) {

   return s_colPlayerBitmaps;

  }

  //Загрузить изображения как ресурсы из исполняемого двоичного файла

  System.Reflection.Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();

  System.Reflection.AssemblyName thisAssemblyName = thisAssembly.GetName();

  string assemblyName = thisAssemblyName.Name;

  //Загрузить изображения

  s_Player_Bitmap1 = new System.Drawing.Bitmap(

   thisAssembly.GetManifestResourceStream(assemblyName + ".Hank_RightRun1.bmp"));

  s_Player_Bitmap2 = new System.Drawing.Bitmap(

   thisAssembly.GetManifestResourceStream(assemblyName + ".Hank RightRun2.bmp"));

  s_Player_Bitmap3 = new System.Drawing.Bitmap(

   thisAssembly.GetManifestResourceStream(assemblyName + ".Hank_LeftRun1.bmp"));

  s_Player_Bitmap4 = new System.Drawing.Bitmap(

   thisAssembly.GetManifestResourceStream(assemblyName + ".Hank_LeftRun2.bmp"));

  //Добавить изображения в коллекцию

  s_colPlayerBitmaps = new System.Collections.ArrayList();

  s_colPlayerBitmaps.Add(s_Player_Bitmap1);

  s_colPlayerBitmaps.Add(s_Player_Bitmap2);

  s_colPlayerBitmaps.Add(s_Player_Bitmap3);

  s_colPlayerBitmaps.Add(s_Player_Bitmap4);

 //Возвратить коллекцию

 return s_colPlayerBitmaps;

 }

 private static System.Drawing.Pen s_blackPen;

 private static System.Drawing.Pen s_whitePen;

 private static System.Drawing.Imaging.ImageAttributes s_ImageAttribute;

 private static System.Drawing.Font s_boldFont;

 //------------------------------------------------

 //Вызывается для освобождения от любых графических

 //ресурсов, которые могли быть кэшированы

 //------------------------------------------------

 private static void g_CleanUpDrawingResources() {

  //Освободить память от черного пера, если таковое имеется

1 ... 60 61 62 63 64 65 66 67 68 ... 206
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Программирование мобильных устройств на платформе .NET Compact Framework - Иво Салмре.
Комментарии