Синхронизация с помощью атрибута [Synchronization]

Синхронизация с помощью атрибута [Synchronization]

Последним из рассмотренных здесь примитивов синхронизации будет атрибут [Synchronization], который определяется в пространстве имен System.Runtime.Remoting.Contexts. Этот атрибут уровня класса для безопасности потока эффективно блокирует весь программный код членов экземпляра. Когда среда CLR размещает объект, имеющий атрибут [Synchronization], она помещает этот объект в рамки синхронизированного контекста. Вы должны помнить из главы 13, что объекты, которые не должны покидать контекстные границы, являются производными от ContextBoundObject. Поэтому, чтобы сделать тип класса Printer устойчивым в отношении потоков (без добавления программного кода защиты потоков вручную), следует изменить соответствующее определение так.

using System.Runtime.Remoting.Contexts;

...

// Все методы Printer теперь потокоустойчивы!

[Synchronization]

public class Printer: СontextBoundObject {

 public void PrintNumbers() {

 …

 }

}

Этот подход можно назвать способом создания потокоустойчивого программного кода для ленивых, поскольку здесь не требуется выяснять, какие фрагменты типа могут испытывать влияние внешних потоков. Главным недостатком этого подхода является то, что даже если какой-то метод и не испытывает влияния внешних потоков, среда CLR все равно блокирует обращение к этому методу. Очевидно, это может ухудшить общие характеристики функционирования типа, так что используйте указанный подход с осторожностью.

Итак, мы с вами обсудили целый ряд подходов к решению вопроса синхронизированного доступа к общим блокам данных. Будьте уверены, в пространстве имен System.Threading есть и другие типы, которые я настоятельно рекомендую вам постепенно исследовать. В завершение этой главы, посвященной программированию потоков, давайте рассмотрим три: дополнительных типа: TimerCallback, Timer и ThreadPool.