Читайте также:
|
|
Т.к. объекты не удаляются сразу же после того, как в них отпадает необходимость, то и собственно освобождение ресурсов происходит с задержкой, и, чаще всего, эта задержка является фатальной. Попробуйте вызвать вот такую процедуру дважды:
void Test(){
TextWriter tw = new StreamWriter("test.txt",true);
tw.Write("123");
}
Думаю, исключение System.IO.IOException вам обеспечено по причине «The process cannot access the file "test.txt" because it is being used by another process.» (Процесс не может достучаться до файла, потому что до него уже достучался другой процесс). В общем-то, ничего удивительного, файлы за собой нужно закрывать, но в данном случае это ещё не всё. Даже написав код закрытия файла, нет никакой гарантии, что он точно будет выполнен. Что будет, если между открытием и закрытием файла произойдёт исключение? Даже если мы и обработаем это исключение позже, то наш файл опять не будет вовремя закрыт. Чтобы в данном случае обеспечить корректную работу, нам нужен примерно следующий код:
void Test(){
TextWriter tw = null;
try {
tw = new StreamWriter("test.txt",true);
tw.Write("123");
}
finall {
if (tw!= null)
tw.Close();
}
}
Вот теперь всё будет работать как надо. Для этого нам всего лишь понадобилось добавить ещё девять строчек кода к исходным двум.
Видимо, всё это прекрасно понимают и в самой Microsoft. Поэтому, в конце концов, для решения этой проблемы в C# было введено ключевое слово using, представляющее собой языковую конструкцию, заменяющую блок try/finally.
Перепишем наш пример с использованием using:
void Test(){
using (TextWriter tw = new StreamWriter("test.txt",true)) {
tw.Write("123");
}
}
Это уже гораздо лучше. Конструкция using генерирует код, аналогичный нашему примеру с try/finally, за тем исключением, что вместо метода Close она вызывает Dispose. Вполне логично предположить, что объект должен иметь в своём составе такой метод. Так и есть, мы можем использовать с этой конструкцией только те объекты, которые реализуют интерфейс IDisposable, содержащий в своём составе один единственный метод:
void Dispose();
16. «Мягкие ссылки» и кэширование данных в среде.NET.
В программировании слабая ссылка (англ. weak reference) — специфический вид ссылок на динамически создаваемые объекты в системах со сборкой мусора. Отличается от обычных ссылок тем, что не учитывается сборщиком мусора при выявлении объектов, подлежащих удалению. Ссылки, не являющиеся слабыми, также иногда именуют «сильными». Такие ссылки используются так же, как и обычные, но не влияют на сборку мусора, поскольку не учитываются механизмом подсчёта ссылок, и объект, на который существуют такие ссылки, может быть удалён, если только на него не существует обычных ссылок (которые в этом контексте могут именоваться «сильными ссылками»).
Слабые ссылки поддерживаются на уровне системных библиотек в C# — класс System.WeakReference. Когда требуется сохранить слабую ссылку, создаётся объект-реферер (экземпляр класса WeakReference), которому передаётся сильная ссылка. Переданная сильная ссылка тут же освобождается, и в реферере хранится ссылка, существование которой не может помешать сборщику мусора удалить соответствующий объект. Когда требуется воспользоваться слабой ссылкой, у реферера вызывается метод get() (в C# — свойство Target), который возвращает сильную ссылку на объект, если он ещё существует, или null, если объект уже удалён сборщиком мусора. Поскольку get возвращает именно сильную ссылку, во время её использования объект удалён не будет, но после того, как использование этой ссылки прекратилось, он снова становится доступным для сборки мусора. Таким образом, при каждом использовании слабой ссылки программа должна обязательно проверить её на равенство NULL.
Чтобы слабые ссылки на уже не существующие объекты не засоряли память, системные библиотеки предоставляют механизмы для учёта таких ссылок. Вариантом такого механизма являются очереди ссылок — специальные объекты, которые передаются рефереру при создании. Когда сборщик мусора уничтожает объект, на который ссылается слабая ссылка, он помещает в ранее переданную очередь ссылок ссылку на соответствующий реферер. Таким образом, программе доступен список рефереров, содержащих «мёртвые» ссылки, и она может выполнить их удаление в любой подходящий момент.
Кэш данных является наиболее часто используемым хранилищем информации в приложениях ASP.NET. Это кэш, хранящийся в памяти и доступный через объект Cache. Чтобы добавить новый элемент в кэш, вам понадобится указать ключ для него (где ключом является строка). Аналогично для того, чтобы получить элемент из кэша, вам понадобится сослаться на него, используя ключ.
Элементы управления ObjectDataSource, SqlDataSource, AccessDataSource и XmlDataSource содержат свойства, которые указывают элементам управления источником данных, что необходимо кэшировать информацию в кэше данных. Данное кэширование выполняется автоматически и не требует написания кода. Ключевыми свойствами являются:
EnableCaching - значение типа Boolean, от которого зависит, будет произведено кэширование или нет. По умолчанию оно установлено в False. Вам понадобится установить данное значение в True, чтобы элемент управления источником данных выполнял кэширование.
CacheDuration - значение типа Integer, которое указывает длительность кэширования информации (в секундах).
CacheExpirationPolicy - указывает тип окончания кэширования - может быть установлен в Absolute (абсолютное) либо Sliding (плавное). Абсолютное означает то, что элемент кэша будет удален через определенное в CacheDuration время с момента его записи в кэше. Плавный тип подразумевает удаление из кэша через время, указанное в CacheDuration с момента последнего доступа к данным. По умолчанию установлено в Absolute.
CacheKeyDependency - значение типа String, которое указывает на дополнительный элемент в кэше, служащий в качестве отношения. Если указано данное значение, то когда изменяется кэшированный элемент в CacheKeyDependency, источник данных также изменит информацию в кэше.
Одним из недостатков кэширования информации является старение данных. Кроме удаления кэшированной информации по истечению какого-либо срока, существуют другие способы удаления. Элементы управления источником данных автоматически высвобождают данные из кэша, если вызывается метод Insert, Update или Delete элемента управления источником данных. Вкратце, методы элемента управления источником данных изменяют хранилище данных, как об этом свидетельствуют их имена, и также могут быть декларативно настроены. Когда выполняется какой-либо из этих методов, элемент управления источником данных изменяет хранилище данных, таким образом благоразумно удаляя кэшированную информацию, поскольку известно, что она уже не является настолько новой.
17. Динамические массивы в среде. NET и языке C#.
Динамическим считается массив, который способен в любой момент изменять свой размер. Эта возможность обеспечивается за счет динамического выделения памяти под массив. При этом удобно создать класс, который является оболочкой для данного массива, отвечает за выделение и освобождение памяти под массив, а также обеспечивает доступ к элементам массива.
Когда пользователь создает объект класса-оболочки, конструктор класса выделяет память под массив, который имеет либо указанный пользователем размер, либо размер, заданный по умолчанию. Если по мере заполнения массива вся выделенная память окажется занятой, то при добавлении очередного элемента выделенная ранее память освобождается, все хранящиеся в массиве значения сохраняются во временном массиве. Затем выделяется память под массив большего размера и в него помещаются сохраненные значения. Таким образом, изменение размера массива происходит автоматически, невидимо для пользователя.
В C# все массивы, независимо от того, каким выражением описывается граница, рассматриваются как динамические, и память для них распределяется в "куче". Полагаю, что это отражение разумной точки зрения: ведь статические массивы, скорее исключение, а правилом является использование динамических массивов. В действительности реальные потребности в размере массива, скорее всего, выясняются в процессе работы в диалоге с пользователем.
Чисто синтаксически нет существенной разницы в объявлении статических и динамических массивов. Выражение, задающее границу изменения индексов, в динамическом случае содержит переменные. Единственное требование - значения переменных должны быть определены в момент объявления. Это ограничение в C# выполняется автоматически, поскольку хорошо известно, сколь требовательно C# контролирует инициализацию переменных.
public void TestDynAr()
{
//объявление динамического массива A1
Console.WriteLine("Введите число элементов массива A1");
int size = int.Parse(Console.ReadLine());
int[] A1 = new int[size];
Arrs.CreateOneDimAr(A1);
Arrs.PrintAr1("A1",A1);
}//TestDynAr
Для поддержки работы с массивами создан специальный класс Arrs, статические методы которого выполняют различные операции над массивами.
Дата добавления: 2015-01-30; просмотров: 102 | Поможем написать вашу работу | Нарушение авторских прав |