- •1. Сборщик мусора и управление ресурсами
- •2. Жизненный цикл объектов
- •3. Неуправляемый код и указатели
- •4. Строки и строковый пул
- •5. Обобщенные типы, ограничения в параметрах обобщенных типов, типы допускающие null значение
- •6. Тип Type и пространство System.Reflection
- •7. Создание объектов с помощью рефлексии, вызов методов объектов средствами рефлексии
- •8. Атрибуты, жизненный цикл объекта атрибута
- •9. Специальные атрибуты net.Framework и ограничения пользовательских атрибутов
- •10. Метаданные сборок, структура сборок, домены приложений
- •11. Многопоточное программирование. Виды многопоточности, обеспечение многопоточности в net.Framework, виды блокировки
- •12. Класс Thread, логические и физические потоки выполнения, жизненный цикл потока выполнения
- •13. Класс монитора, конструкция lock()
- •14. Атомарная синхронизация и класс Interlocked
- •15. Класс ReaderWriterLock, пул потоков
- •16. Классы WaitHandle и производные от него: ManualResetEvent, AutoResetEvent, Mutex
- •17. Высокоуровневые средства распараллеливания задач, класс Task
- •18. Свойства и методы класса Task
- •19. Делегаты, цепочка вызова
- •Групповая адресация
- •20. Асинхронный вызов с помощью объекта делегата
- •IAsyncResult
- •21. События, обратный вызов, типовая схема реализации события
- •22. Лямбда-выражения, замыкание лямбда-выражений
- •23. Деревья выражений, типы деревьев. Создание деревьев выражений
- •24. Технология ado.Net, архитектура, модель с постоянным соединением и с рассоединением
- •Linq to DataSet
- •Linq to sql
- •Платформа ado.Net Entity Framework
- •Службы wcf Data Services
- •25)Понятие поставщика данных и его составные части в ado.Net. Класс соединения, итератора, команды.
- •26. Технология объектно-реляционного связывания, персистентные объекты, на примере одной из технологии (Linq to sql, Linq to Entities, nHibernate)
- •Entity Framework
- •27. Linq to Objects: архитектура технологии и возможности, понятие итератора, создание Linq запросов
- •28. Средства распараллеливания выполнения запросов plinq.
- •29. Основы wcf. Основные понятия, применение. Контракты данных, привязки. Архитектура сервис-ориентированных систем.
- •1) Библиотека с интерфейсом
- •2) Сервер – консольное приложение
- •3) Клиент – консольное приложение
- •30. Структура проекта с использованием wcf сервисов. Интерфейсы сервиса, атрибуты для обозначения методов сервиса и контрактов данных.
- •1) Библиотека с интерфейсом
- •2) Сервер – консольное приложение
- •3) Клиент – консольное приложение
- •31. Методы и свойства прокси-объекта на стороне клиента.
- •32. Развертывание wcf сервисов.
2. Жизненный цикл объектов
В С# общий принцип управления памятью формулируется очень просто: для создания объекта в области «управляемой кучи» (managed heap) используется ключевое слово new. Среда выполнения .NET автоматически удалит объект тогда, когда он больше не будет нужен. Правило в целом вполне понятно, однако возникает один дополнительный вопрос: а как среда выполнения определяет, что объект больше не нужен? Короткий (то есть неполный) ответ гласит, что среда выполнения удаляет объект из памяти, когда в текущей области видимости больше не остается активных ссылок на этот объект.
Вне зависимости от того, насколько осторожно вы будете создавать объекты, как только место в управляемой куче заканчивается, автоматически запускается сборщик мусора (garbage collector, GC).
Декструктор/ Finalize
class Car
{
~Car() // destructor
{
// cleanup statements...
}
}
Деструктор неявным образом вызывает метод Finalize для базового класса объекта. Следовательно, предыдущий код деструктора неявным образом преобразуется в следующий код:
protected override void Finalize()
{
try
{
// Cleanup statements...
}
finally
{
base.Finalize();
}
}
Это
означает, что метод Finalize вызывается
рекурсивно для всех экземпляров цепочки
наследования начиная с самого
дальнего и заканчивая самым первым.
Высвобождение ресурсов явным образом
В
случае, когда приложением используется
ценный внешний ресурс, также рекомендуется
обеспечить способ высвобождения этого
ресурса явным образом, прежде чем сборщик
мусора освободит этот объект. Это
выполняется путем реализации
метода Dispose интерфейса IDisposable,
который выполняет необходимую очистку
для объекта. Это
может значительно повысить производительность
приложения. Даже
в случае использования данного явного
управления ресурсами деструктор
становится резервным средством очистки
ресурсов, если вызов метода Dispose не
будет выполнен.
Сборщик мусора
Вопрос №1
3. Неуправляемый код и указатели
Для обеспечения строгой типизации и безопасности C# по умолчанию не поддерживает арифметические операции над указателями. Однако с помощью ключевого слова unsafe можно определить небезопасный контекст для использования указателей.
В среде CLR небезопасный код называют непроверяемым. Небезопасный код в C# не обязательно представляет опасность. Это просто код, безопасность которого не может быть проверена средой CLR. Поэтому CLR выполнит этот код, только если он находится в полностью надежной сборке. При использовании небезопасного кода необходимо обеспечить гарантию того, что он не создаст угрозу безопасности и не вызовет ошибки указателей.
Небезопасный код имеет следующие свойства.
Методы, типы и блоки кода могут определяться как небезопасные.
В некоторых случаях небезопасный код может повысить производительность приложения за счет удаления проверок границ массива.
Использование небезопасного кода необходимо при вызове встроенных функций, требующих указателей.
Использование небезопасного кода создает угрозу безопасности и стабильной работы.
Для компиляции небезопасного кода в C# необходимо, чтобы приложение было скомпилировано с помощью /unsafe.
Указатели.
В небезопасном контексте тип может быть типом указателя, типом значения или ссылочным типом. Объявления типа указателя выполняется одним из следующих способов:
{type}* identifier;
Указатель не может указывать на ссылку или на структуру, содержащую ссылки, поскольку ссылка на объект может быть подвергнута сбору мусора, даже если на нее указывает указатель. Сборщик мусора не отслеживает наличие указателей любых типов, указывающих на объекты.
int a = 10;
// Должно быть в небезопасном коде, чтобы использовать внутренние указатели.
unsafe
{
fixed (int* p = &a)
{
int* p2 = p;
Console.WriteLine(*p2);
}
}
Оператор fixed не позволяет сборщику мусора переносить перемещаемую переменную. Оператор fixed допускается только в небезопасном контексте. Оператор fixed задает указатель на управляемую переменную и "закрепляет" эту переменную во время выполнения оператора. Без fixed, указатели на перемещаемые управляемые переменные были бы мало полезны, так как при сборке мусора переменные переносились бы непредсказуемым образом. Компилятор C# позволяет назначить указатель только управляемой переменной в операторе fixed.
