Книга: C# 4.0: полное руководство
Применение атрибута MethodlmplAttribute
Применение атрибута MethodlmplAttribute
Метод может быть полностью синхронизирован с помощью атрибута MethodlmplAttribute
. Такой подход может стать альтернативой оператору lock
в тех случаях, когда метод требуется заблокировать полностью. Атрибут MethodlmplAttгibute
определен в пространстве имен System.Runtime.CompilerServices
. Ниже приведен конструктор, применяемый для подобной синхронизации:
public MethodlmplAttribute(MethodlmplOptions methodlmplOptions)
где methodlmplOptions обозначает атрибут реализации. Для синхронизации метода достаточно указать атрибут MethodlmplOptions.Synchronized
. Этот атрибут вызывает блокировку всего метода для текущего экземпляра объекта, доступного по ссылке this
. Если же метод относится к типу static
, то блокируется его тип. Поэтому данный атрибут непригоден для применения в открытых объектах или классах.
Ниже приведена еще одна версия программы, имитирующей тиканье часов, с переделанным вариантом класса TickTock
, в котором атрибут MethodlmplOptions
обеспечивает должную синхронизацию.
// Использовать атрибут MethodlmplAttribute
// для синхронизации метода.
using System;
using System.Threading;
using System.Runtime.CompilerServices;
//Вариант класса TickTock, переделанный с целью
// использовать атрибут MethodlmplOptions.Synchronized,
class TickTock {
/* Следующий атрибут полностью синхронизирует метод Tick(). */
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public void Tick(bool running) {
if (!running) { // остановить часы
Monitor.Pulse(this); // уведомить любые ожидающие потоки
return;
}
Console.Write("тик ");
Monitor.Pulse(this); // разрешить выполнение метода Tock()
Monitor.Wait(this); // ожидать завершения метода Tock()
}
/* Следующий атрибут полностью синхронизирует метод Тоск(). */
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public void Tock(bool running) {
if (!running) { // остановить часы
Monitor.Pulse(this); // уведомить любые ожидающие потоки
return;
}
Console.WriteLine("так");
Monitor.Pulse(this); // разрешить выполнение метода Tick()
Monitor.Wait(this); // ожидать завершения метода Tick()
}
}
class MyThread {
public Thread Thrd;
TickTock ttOb;
// Сконструировать новый поток.
public MyThread(string name, TickTock tt) {
Thrd = new Thread(this.Run);
ttOb = tt;
Thrd.Name = name;
Thrd.Start();
}
// Начать выполнение нового потока,
void Run() {
if (Thrd.Name == "Tick") {
for (int i = 0; i < 5; i++) ttOb.Tick(true);
ttOb.Tick(false);
}
else {
for (int i = 0; i < 5; i++) ttOb.Tock(true);
ttOb.Tock(false);
}
}
}
class TickingClock {
static void Main() {
TickTock tt = new TickTock();
MyThread mt1 = new MyThread("Tick", tt);
MyThread mt2 = new MyThread("Tock", tt);
mt1.Thrd.Join();
mt2.Thrd.Join();
Console.WriteLine("Часы остановлены");
}
}
Эта версия программы дает такой же результат, как и предыдущая. Синхронизируемый метод не определен в открытом классе и не вызывается для открытого объекта, поэтому применение оператора lock
или атрибута MethodlmplAttribute
зависит от личных предпочтений. Ведь и тот и другой дает один и тот же результат. Но поскольку ключевое слово lock
относится непосредственно к языку С#, то в примерах, приведенных в этой книге, предпочтение отдано именно ему.
----------------------------
ПРИМЕЧАНИЕ
Не применяйте атрибут MethodImplAttribute
в открытых классах или экземплярах открытых объектов. Вместо этого пользуйтесь оператором lock, чтобы заблокировать метод для закрытого объекта, как пояснялось ранее.
----------------------------
- Основы многопоточной обработки
- Класс Thread
- Определение момента окончания потока
- Передача аргумента потоку
- Свойство IsBackground
- Приоритеты потоков
- Синхронизация
- Сообщение между потоками с помощью методов Wait(), Pulse() и PulseAll()
- Взаимоблокировка и состояние гонки
- Применение атрибута MethodlmplAttribute
- Применение мьютекса и семафора
- Применение событий
- Класс Interlocked
- Классы синхронизации, внедренные в версии .NET Framework 4.0
- Прерывание потока
- Приостановка и возобновление потока
- Определение состояния потока
- Применение основного потока
- Дополнительные средства многопоточной обработки, внедренные в версии .NET Framework 4.0
- Рекомендации по многопоточному программированию
- Запуск отдельной задачи
- Применение основного потока
- Применение функции scanf( )
- Применение PHP-технологий в программе HtmlPad
- 17.6 Применение агентов новостей для настольных систем
- 2.3. Эмпирическая модель обучения Дэвида Колба и ее применение в практике бизнес-тренинга
- Применение пользовательских атрибутов
- Применение peristaltic.py к арматуре
- Применение лямбда-выражения в качестве задачи
- Проблемы в команде и применение к ним принципов осознанной практики
- Глава 3 Создание и применение шаблонов
- 4.2. Модели безопасности и их применение
- Применение мьютекса и семафора