- •Сборки (assembly) в среде .Net. Проблема версионности сборок и ее решение.
- •Номер версии в .Net
- •Сведения о версии
- •Номер версии сборки
- •Информационная версия сборки
- •Общая система типов данных в среде .Net. Размерные и ссылочные типы данных. Типы, переменные и значения
- •Пользовательские типы
- •Система общих типов cts
- •Ссылочные типы
- •Типы литеральных значений
- •Неявные типы, анонимные типы и типы, допускающие значение null
- •Упаковка и распаковка размерных типов данных в среде .Net.
- •Производительность
- •Упаковка–преобразование
- •Распаковка-преобразование
- •Ссылочные типы данных. Объектная модель в среде .Net и языке c#.
- •Модели ручной и автоматической утилизации динамической памяти, их сравнительная характеристика. Модель с ручным освобождением памяти
- •Модель с автоматической «сборкой мусора»
- •Модель автоматической утилизации динамической памяти, основанная на сборке мусора. Проблема недетерминизма.
- •Модель автоматической утилизации динамической памяти, основанная на аппаратной поддержке (тегированной памяти).
- •Сборка мусора в среде .Net. Построение графа достижимых объектов.
- •Сборка мусора в среде .Net. Механизм поколений объектов.
- •Модель детерминированного освобождения ресурсов в среде .Net. Интерфейс iDisposable и его совместное использование с завершителем (методом Finalize).
- •«Мягкие ссылки» и кэширование данных в среде .Net.
- •Краткие и длинные слабые ссылки
- •Краткая ссылка
- •Длинная ссылка
- •Правила использования слабых ссылок
- •Динамические массивы в среде .Net и языке c#.
- •Приведение типов в массивах
- •Все массивы неявно реализуют /Enumerable, /Collection и iList
- •Передача и возврат массивов
- •Создание массивов с ненулевой нижней границей
- •Производительность доступа к массиву
- •Небезопасный доступ к массивам и массивы фиксированного размера
- •Делегаты в среде .Net и механизм их работы. Знакомство с делегатами
- •Использование делегатов для обратного вызова статических методов
- •Использование делегатов для обратного вызова экземплярных методов
- •Правда о делегатах
- •Использование делегатов для обратного вызова множественных методов (цепочки делегатов)
- •Поддержка цепочек делегатов в с#
- •Расширенное управление цепочкой делегатов
- •Упрощение синтаксиса работы с делегатами в с#
- •Упрощенный синтаксис № 1: не нужно создавать объект-делегат
- •Упрощенный синтаксис № 2: не нужно определять метод обратного вызова
- •Упрощенный синтаксис № 3: не нужно определять параметры метода обратного вызова
- •Упрощенный синтаксис № 4: не нужно вручную создавать обертку локальных переменных класса для передачи их в метод обратного вызова
- •Делегаты и отражение
- •События в среде .Net; реализация событий посредством делегатов. События
- •Этап 1: определение типа, который будет хранить всю дополнительную информацию, передаваемую получателям уведомления о событии
- •Этап 2: определение члена-события
- •Этап 3: определение метода, ответственного за уведомление зарегистрированных объектов о событии
- •Этап 4: определение метода, транслирующего входную информацию в желаемое событие
- •Как реализуются события
- •Создание типа, отслеживающего событие
- •События и безопасность потоков
- •Явное управление регистрацией событий
- •Конструирование типа с множеством событий
- •Исключительные ситуации и реакция на них в среде .Net. Достоинства
- •Механика обработки исключений
- •Блок try
- •Блок catch
- •Блок finally
- •Генерация исключений
- •Определение собственных классов исключений
- •Исключения в платформе .Net Framework
- •Исключения и традиционные методы обработки ошибок
- •Управление исключениями средой выполнения
- •Фильтрация исключений среды выполнения
- •21 Средства многопоточного программирования в среде .Net. Автономные потоки. Пул потоков.
- •Создание и использование потоков
- •Запуск и остановка потоков
- •Методы управления потоками
- •Безопасные точки
- •Свойства потока
- •Потоки Windows в clr
- •К вопросу об эффективном использовании потоков
- •Пул потоков в clr
- •Ограничение числа потоков в пуле
- •22. Асинхронные операции в среде .Net. Асинхронный вызов делегатов.
- •23. Синхронизация программных потоков в среде .Net. Блокировки.
- •Двойная блокировка
- •Класс ReaderWriterLock
- •Использование объектов ядра Windows в управляемом коде
- •Вызов метода при освобождении одного объекта ядра
- •24. Синхронизация программных потоков в среде .Net. Атомарные (Interlocked-операции). Семейство lnterlocked-методов
- •25. Прерывание программных потоков в среде .Net. Особенности исключительной ситуации класса ThreadAbortException.
- •26. Мониторы в среде .Net. Ожидание выполнения условий с помощью методов Wait и Pulse. Класс Monitor и блоки синхронизации
- •«Отличная» идея
- •Реализация «отличной» идеи
- •Использование класса Monitor для управления блоком синхронизации
- •Способ синхронизации, предлагаемый Microsoft
- •Упрощение кода c# при помощи оператора lock
- •Способ синхронизации статических членов, предлагаемый Microsoft
- •Почему же «отличная» идея оказалась такой неудачной
- •Целостность памяти, временный доступ к памяти и volatile-поля
- •Временная запись и чтение
- •Поддержка volatile-полей в с#
- •27. Асинхронный вызов делегатов.
- •Общие типы (Generics)
- •Инфраструктура обобщений
- •Открытые и закрытые типы
- •Обобщенные типы и наследование
- •Проблемы с идентификацией и тождеством обобщенных типов
- •«Распухание» кода
- •Обобщенные интерфейсы
- •Обобщенные делегаты
- •Обобщенные методы
- •Логический вывод обобщенных методов и типов
- •Обобщения и другие члены
- •Верификация и ограничения
- •Основные ограничения
- •Дополнительные ограничения
- •Ограничения конструктора
- •Другие вопросы верификации
- •Приведение переменной обобщенного типа
- •Присвоение переменной обобщенного типа значения по умолчанию
- •Сравнение переменной обобщенного типа с null
- •Сравнение двух переменных обобщенного типа
- •Использование переменных обобщенного типа в качестве операндов
- •Преимущества использования общих типов
- •29. Итераторы в среде .Net. Создание и использование итераторов.
- •Общие сведения о итераторах
Исключительные ситуации и реакция на них в среде .Net. Достоинства
Компактное размещение кода, выполняющего очистку, и его гарантированное исполнение.
Централизованное хранение кода, имеющего дело с исключительными ситуациями.
Облегчение поиска и исправления ошибок в коде
Механика обработки исключений
Механизм обработки исключений .NET Framework построен с использованием механизма структурной обработки исключений (structured exception handling, SEH) Windows.
Следующий код на С# демонстрирует стандартное применение механизма обработки исключений. Он дает представление о том, как выглядят и для чего нужны блоки обработки исключений. В комментариях дано формальное описание блоков try, catch и finally и указано их назначение.
private void SomeMethod()
{
try
{
// Внутрь блока try помещают код, требующий корректного
// восстановления работоспособности или очистки ресурсов.
}
catch (InvalidOperationException)
{
// В такие блоки catch помещают код, который должен восстанавливаться
// после исключений типа InvalidOperationException (или любого исключения,
// производного от него).
}
catch (IOException)
{
// В такие блоки catch помещают код, который должен восстанавливаться
// после исключений типа IOException (или любого исключения,
// производного от него).
}
catch
{
// В такие блоки catch помещают код, который должен
// восстанавливаться после исключений любого типа.
// После перехвата исключений их, как правило,
// генерируют повторно. Ниже я еще вернусь к этому.
throw;
}
finally
{
// Внутрь блоков finally помещают код, выполняющий очистку ресурсов
// после любых действий, начатых в блоке try. Код из этого блока
// исполняется ВСЕГДА независимо от того, было исключение или нет.
}
// Код после блока finally исполняется, если в блоке try не было
// исключения или если исключение было перехвачено блоком catch
// и не было сгенерировано то же самое или другое исключение.
}
Код демонстрирует один из возможных способов использования блоков для обработки исключений.
Блок try
Блок try содержит код, требующий общей очистки ресурсов или восстановления после исключения. Код очистки должен размещаться в единственном блоке finally. В блоке try также может быть код, способный с определенной вероятностью сгенерировать исключение. Код восстановления после исключения надо разместить в одном или нескольких блоках catch. Следует создать по одному блоку catch для каждого вида событий, после которых, по вашим прогнозам, придется восстанавливать приложение. Блок try должен быть связан хотя бы с одним блоком catch или finally, сами по себе блоки try бессмысленны.
Блок catch
Блок catch содержит код, который должен выполняться при возникновении исключения. У блока try может быть несколько или ни одного связанного с ним блока catch. Если код из блока try не вызывает исключение, CLR никогда не исполнит код из соответствующих блоков catch. Поток пропускает все эти блоки и начинает исполнять код блока finally. Исполнив код блока finally, поток переходит к оператору, следующему за этим блоком.
Выражение, расположенное в скобках после ключевого слова catch, называют типом исключения (catch type). В Сопрограммах тип исключения должен содержать тип SystemException или его потомок. Так, показанный выше код содержит блоки catch, обрабатывающие исключения типа InvalidOperationException (и его производные), lOException (и его производные). Последний блок catch (в нем тип исключения не указан) обрабатывает любые другие исключения; такой блок равносилен блоку catch с типом исключения SystemException, если только нельзя получить доступ об исключении из кода, расположенного в блоке catch.
CLR просматривает блоки catch сверху вниз, поэтому «узкоспециализированные» исключения надо размещать выше.
Если при исполнении кода из блока try (или любого метода, вызванного в блоке try) возникает исключение, CLR начинает поиск блоков catch с типами, соответствующими этому исключению. Если ни один из этих фильтров не принимает исключение, CLR продолжает просматривать стек вызовов в поисках фильтра перехвата, который принял бы это исключение. Если по достижении вершины стека вызовов блок catch, способный обработать это исключение, не найден, оно считается необработанным.
Обнаружив фильтр блока, способного обработать исключение, CLR исполняет все внутренние блоки finally. Первым исполняется тот, что связан с блоком try, в котором возникло исключение, а последним — блок catch, тип которого соответствует исключению. Заметьте: ни один блок finally, связанный с блоками catch, не исполняется, пока не завершено исполнение кода из блока catch, обрабатывающего исключение.
В конце концов, по исполнении кода блоков finally исполняется код из обрабатывающего блока catch. Как правило, этот код выполняет некоторые действия для восстановления после исключения. Затем можно выбрать одно из трех:
■ сгенерировать то же исключение повторно, чтобы уведомить о нем код, расположенный выше по стеку вызовов;
■ сгенерировать исключение другого типа, чтобы передать коду, расположенному выше по стеку вызовов, больше сведений об исключении;
■ позволить потоку покинуть блок catch.
Если выбран первый или второй вариант, генерируется исключение и CLR действует как обычно: просматривает стек вызовов в поисках блока catch, тип которого соответствует сгенерированному исключению.
Если выбран последний вариант, поток выходит из блока catch и тут же переходит к исполнению кода из блока finally, если таковой есть. После исполнения блока finally поток покидает этот блок и переходит к выполнению оператора, расположенного сразу после блока finally. Если блока finally нет, поток переходит к исполнению оператора, стоящего за последним блоком catch.
В С# после типа перехвата можно указать имя переменной. При перехвате исключения эта переменная ссылается на сгенерированный объект, потомок SystemException. В коде блока catch ее можно использовать для получения информации об исключении (в частности, трассировочного следа в стеке вплоть до исключения).