Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ОСиСП.doc
Скачиваний:
71
Добавлен:
11.05.2015
Размер:
1.78 Mб
Скачать

Краткие и длинные слабые ссылки

Можно создать краткую слабую ссылку или длинную слабую ссылки.

Краткая ссылка

Назначением краткой ссылки становится null, если объект удален сборщиком мусора. Сама по себе слабая ссылка является управляемым объектом и подлежит сборке мусора, как и любые другие управляемые объекты. Краткая слабая ссылка является конструктором по умолчанию для WeakReference.

Длинная ссылка

Длинная слабая ссылка сохраняется после вызова метода Finalizeобъекта. Это позволяет повторно создавать объект, однако состояние объекта остается непредсказуемым. Чтобы использовать длинную ссылку, укажите значение true в конструктореWeakReference.

Если тип объекта не имеет метода Finalize, используется функциональность краткой слабой ссылки, а сама слабая ссылка становится допустимой только до сборки цели, что может произойти в любое время после запуска метода завершения.

Чтобы установить строгую ссылку и повторно использовать объект, приведите свойство TargetобъектаWeakReferenceк типу объекта. Если свойствоTargetвозвращает значение null, объект был собран; в противном случае можно продолжить использование объекта, так как приложение восстановило строгую ссылку на этот объект.

Правила использования слабых ссылок

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

Избегайте использования слабых ссылок на небольшие объекты, потому что сам указатель может быть таким же по объему или даже больше.

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

Пример

class Class1

{

class TestClass

{

public override string ToString()

{

return "Test Object No " + objectNo;

}

public TestClass()

{

objectNo++;

}

static int objectNo = 0;

}

// «слабая» ссылка

WeakReference wr = new WeakReference(null);

// Возвращает ссылку на объект,

// при необходимости создаёт новый

TestClass GetRef()

{

// Если объект уже создан и всё ещё жив,

// то мы можем получить ссылку на него через Target

TestClass tc = (TestClass)wr.Target;

if (tc == null)

{

tc = new TestClass();

wr.Target = tc;

}

return tc;

}

public void Test()

{

// Получаем ссылку на объект

object obj = GetRef();

// Вызываем сборщик мусора,

// но объект не будет удалён,

// т.к. существует «сильная» ссылка obj

GC.Collect();

// Печатаем "Test Object No 1"

Console.WriteLine(GetRef());

// удаляем «сильную» ссылку

obj = null;

// Печатаем опять "Test Object No 1",

// т.к. сборщик мусора не вызывался и мы можем

// получить объект через «слабую» ссылку

Console.WriteLine(GetRef());

// Вызываем сборщик мусора ещё раз

GC.Collect();

// На этот раз печатаем "Test Object No 2",

// сборщик мусора удалил старый объект,

// и вызова GetRef создаст новый

Console.WriteLine(GetRef());

}

}

Вопрос № 17