751
Контексты.исполнения
использовать вспомогательные потоки, при этом создаются и инициализируются
дополнительные структуры данных.
Класс
ExecutionContext
в пространстве имен
System.Threading
позволяет
управлять копированием контекста исполнения потока. Вот как он выглядит:
public sea
led class ExecutionContext : IDisposable, ISerializable {
[SecurityCritical] public static AsyncFlowControl SuppressFlow();
public static void RestoreFlow();
public static Boolean IsFlowSuppressed();
// Не показаны редко применяемые методы
}
С помощью этого класса можно запретить копирование
контекста исполнения,
повысив производительность приложения. Для серверных приложений рост про-
изводительности в этом случае оказывается весьма значительным. Для клиентских
приложений особой выгоды нет, кроме того,
метод
SuppressFlow
помечается атри-
бутом
[SecurityCritical]
, в результате становится невозможным вызов некоторых
клиентских приложений (например, Microsoft Silverlight). Разумеется, запрещать
копирование
контекста исполнения можно, только если вспомогательному пото-
ку не требуется содержащаяся там информация. Когда инициирующий контекст
исполнения не переходит во вспомогательный поток,
тот использует последний
связанный с ним контекст исполнения. Поэтому при отключенном копировании
контекста поток не должен исполнять код, зависящий от состояния текущего кон-
текста исполнения (например, идентификационных данных пользователя Windows).
Следующий пример демонстрирует, как запрет на копирование контекста ис-
полнения влияет на данные в контексте логического вызова потока при постановке
рабочего элемента в очередь в CLR-пуле
1
:
public static void Main() {
// Помещаем данные в контекст логического вызова потока метода Main
CallContext.LogicalSetData("Name", "Jeffrey");
// Заставляем поток из пула работать
// Поток из пула имеет доступ к данным контекста логического вызова
ThreadPool.QueueUserWorkItem(
state => Console.WriteLine("Name={0}",
CallContext.LogicalGetData("Name")));
// Запрещаем копирование контекста исполнения потока метода Main
ExecutionContext.SuppressFlow();
// Заставляем поток из пула выполнить работу.
// Поток из пула НЕ имеет доступа к данным контекста логического вызова
ThreadPool.QueueUserWorkItem(
1
Добавляемые к контексту логического вызова элементы должны быть сериализуемыми
(см. главу 24). Копирование контекста исполнения, содержащего данные контекста логи-
ческого вызова, крайне отрицательно сказывается
на производительности, так как требует
серилизации и десериализации всех элементов данных.
продолжение