Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OSISP Part 3.DOC
Скачиваний:
42
Добавлен:
11.05.2015
Размер:
360.45 Кб
Скачать
  1. Асинхронные операции в среде .Net. Асинхронный вызов делегатов.

Чтобы добавить в очередь пула потоков асинхронную вычислительную опе­рацию, обычно вызывают один из следующих методов класса ThreadPool

static Boolean QueueUserWorkItem(WaitCallback callBack);

static Boolean QueueUserWorkItem(WaitCallback callBack, Object state);

static Boolean UnsafeQueueUserWorkItem(WaitCallback callBack, Object state);

Эти методы ставят рабочий элемент (вместе с дополнительными данными состояния) в очередь пула потоков и сразу возвращают управление приложению. Рабочий элемент — это просто указанный в параметре callback метод, который вызывается потоком из пула. Этому методу можно передать один параметр, ука­занный в параметре state (данные состояния). Версия метода QueueUserWorkltem без параметра state передаст null методу обратного вызова. В конце концов один из потоков пула обработает рабочий элемент, что приведет к вызову указанного метода. Создаваемый метод обратного вызова должен соответствовать типу-деле­гату System.ThreadingWaitCallback, который определяется так:

delegate void WaitCallback(Object state);

Метод UnsafeQueueUserWorkltem класса ThreadPool очень похож на чаще исполь­зуемый метод QueueUserWorkItem. Вкратце скажу, чем они различаются. При об­ращении к ограниченному ресурсу (например, при открытии файла) CLR выпол­няет проверку доступа к коду (CAS), то есть наличие разрешений на доступ к ре­сурсу у всех сборок в стеке вызывающего потока. При отсутствии у какой-либо из них нужных разрешений CLR генерирует исключение SecurityException. В част­ности, это исключение возникнет, когда поток, выполняющий код сборки, у ко­торой нет разрешения на открытие файла, все-таки попытается его открыть.

Чтобы обойти это ограничение, поток может поставить рабочий элемент в очередь пула потоков, тогда код открытия файла будет выполнен потоком из пула. Конечно, все это должно происходить в сборке, имеющей необходимые разре­шения. Это «решение» обходит защиту и открывает злоумышленникам доступ к ресурсам с ограниченным доступом. Чтобы устранить эту брешь в защите, метод QueueUserWorkItem просматривает стек вызывающего потока и отслеживает все разрешения на доступ, а затем ассоциирует их с потоком из пула, когда он начи­нает выполняться. Таким образом, поток из пула работает теми же разрешения­ми, что и поток, вызвавший метод QueueUserWorkltem.

Просмотр стека потока и отслеживание всех разрешений на доступ заметно снижают производительность. Чтобы улучшить быстродействие постановки в очередь асинхронной вычислительной операции, можно вместо QueueUserWorkItem вызывать метод UnsafeQueueUserWorkltem, который просто ставит элемент в оче­редь к пулу потоков и не просматривает стек вызывающего потока. В результате этот метод выполняется быстрее, чем QueueUserWorkItem, но создает брешь в за­щите приложения. Поэтому UnsafeQueueUserWorkltem нужно вызывать, только будучи уверенным, что поток из пула будет выполнять код, не обращающийся к ресурсу с ограниченным доступом, или если обращение к этому ресурсу предус­мотрено в приложении. Также учтите, что в коде, вызывающем метод Unsafe­QueueUserWorkltem, должны быть установлены флаги ControlPolicy и ControlEvtdence для SecurityPermissionэто не позволит ненадежному коду случайно или пред­намеренно повысить уровень разрешений.

Асинхронные операции — это ключ к созданию высокопроизводительных, мас­штабируемых приложений, которые позволяют выполнять много операций, ис­пользуя очень небольшое число потоков. А вкупе с пулом потоков они дают воз­можность эффективно задействовать все процессоры в системе. Осознавая этот огромный потенциал, группа разработчиков CLR приступила к созданию модели, которая сделала бы его доступным для всех программистов. Эта модель была на­звана моделью асинхронного программирования (АРМ).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]