- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
C# 4.0 полное руководство - 2011 - Герберт Шилдт
Шрифт:
Интервал:
Закладка:
Событие типа AutoResetEvent отличается от события типа ManualResetEvent лишь способом установки в исходное состояние. Если для события типа ManualResetEvent событийный объект остается в сигнальном состоянии до тех пор, пока не будет вызван метод Reset (), то для события типа AutoResetEvent событийный объект автоматически переходит в несигнальное состояние, как только поток, ожидающий это событие, получит уведомление о нем и возобновит свое выполнение. Поэтому если применяется событие типа AutoResetEvent, то вызывать метод Reset () необязательно.
В приведенном ниже примере программы демонстрируется применение события типа ManualResetEvent.
// Использовать событийный объект, устанавливаемый // в исходное состояние вручную.
using System;
using System.Threading;
// Этот поток уведомляет о том, что событие передано его конструктору, class MyThread {
public Thread Thrd;
ManualResetEvent mre;
public MyThread(string name, ManualResetEvent evt) {
Thrd = new Thread(this.Run);
Thrd.Name = name; ,
mre = evt;
Thrd.Start();
}
// Точка входа в поток, void Run() {
Console.WriteLine("Внутри потока " + Thrd.Name);
for(int i=0; i<5; i++) {
Console.WriteLine(Thrd.Name);
Thread.Sleep(500) ;
}
Console.WriteLine(Thrd.Name + " завершен!");
// Уведомить о событии, mre.Set();
class ManualEventDemo { static void Main() {
ManualResetEvent evtObj = new ManualResetEvent(false);
MyThread mtl = new MyThread("Событийный Поток 1", evtObj);
Console.WriteLine("Основной поток ожидает событие.");
// Ожидать уведомления о событии. evtObj.WaitOne();
Console.WriteLine("Основной поток получил " +
"уведомление о событии от первого потока.");
// Установить событийный объект в исходное состояние. evtObj.Reset();
mtl = new MyThread("Событийный Поток 2", evtObj);
// Ожидать уведомления о событии. evtObj.WaitOne();
Console.WriteLine("Основной поток получил " +
"уведомление о событии от второго потока.");
}
}
Ниже приведен результат выполнения рассматриваемой здесь программы, хотя у вас он может оказаться несколько иным.
В потоке Событийный Поток 1
Событийный Поток 1
Основной поток ожидает событие.
Событийный Поток 1 Событийный Поток 1 Событийный Поток 1 Событийный Поток 1 Событийный Поток 1 завершен!
Основной поток получил уведомление о событии от первого потока.
В потоке Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 Событийный Поток 2 завершен!
Основной поток получил уведомление о событии от второго потока.
Прежде всего обратите внимание на то, что событие типа ManualResetEvent передается непосредственно конструктору класса MyThread. Когда завершается метод Run () из класса MyThread, он вызывает для событийного объекта метод Set (), устанавливающий этот объект в сигнальное состояние. В методе Main () формируется событийный объект evtObj типа ManualResetEvent, первоначально устанавливаемый в исходное, несигнальное состояние. Затем создается экземпляр объекта типа
MyThread, которому передается событийный объект evtObj. После этого основной поток ожидает уведомления о событии. А поскольку событийный объект evtObj первоначально находится в несигнальном состоянии, то основной поток вынужден ожидать до тех пор, пока для экземпляра объекта типа MyThread не будет вызван метод Set () ^устанавливающий событийный объект evtObj в сигнальное состояние. Это дает возможность основному потоку возобновить свое выполнение. Затем событийный объект устанавливается в исходное состояние, и весь процесс повторяется, но на этот раз для второго потока. Если бы не событийный объект, то все потоки выполнялись бы одновременно, а результаты их выполнения оказались бы окончательно запутанными. Для того чтобы убедиться в этом, попробуйте закомментировать вызов метода WaitOne () в методе Main ().
Если бы в рассматриваемой здесь программе событийный объект типа AutoResetEvent использовался вместо событийного объекта типа ManualResetEvent, то вызывать метод Reset () в методе Main () не пришлось бы. Ведь в этом случае событийный объект автоматически устанавливается в несигнальное состояние, когда поток, ожидающий данное событие, возобновляет свое выполнение. Для опробования этой разновидности события замените в данной программе все ссылки на объект типа ManualResetEvent ссылками на объект типа AutoResetEvent и удалите все вызовы метода Reset (). Видоизмененная версия программы будет работать так же, как и прежде.
Класс Interlocked
Еще одним классом, связанным с синхронизацией, является класс Interlocked. Этот класс служит в качестве альтернативы другим средствам синхронизации, когда требуется только изменить значение общей переменной. Методы, доступные в классе Interlocked, гарантируют, что их действие будет выполняться как единая, непрерываемая операция. Это означает, что никакой синхронизации в данном случае вообще не требуется. В классе Interlocked предоставляются статические методы для сложения двух целых значений, инкрементирования и декрементирования целого значения, сравнения и установки значений объекта, обмена объектами и получения 64-разрядно-го значения. Все эти операции выполняются без прерывания.
В приведенном ниже примере программы демонстрируется применение двух методов из класса Interlocked: Increment () и Decrement (). При этом используются следующие формы обоих методов:
public static int Increment(ref int location) public static int Decrement(ref int location)
где location — это переменная, которая подлежит инкрементированию или декрементированию.
// Использовать блокируемые операции.
using System;
using System.Threading;
// Общий ресурс, class SharedRes {
public static int Count = 0;
// В этом потоке переменная SharedRes.Count инкрементируется, class IncThread { '
public Thread Thrd;
public IncThread(string name) {
Thrd = new Thread(this.Run);
Thrd.Name = name;
Thrd.Start();
}
// Точка входа в поток, void Run() {
for(int i=0; i<5; i++) {
Interlocked.Increment(ref SharedRes.Count);
Console.WriteLine(Thrd.Name + " Count = " + SharedRes.Count);
}
}
}
// В этом потоке переменная SharedRes.Count декрементируется, class DecThread { public Thread Thrd;
public DecThread(string name) {
Thrd = new Thread(this.Run);
Thrd.Name = name;
Thrd.Start();
}
// Точка входа в поток, void Run() {
for(int i=0; i<5; i++) {
Interlocked.Decrement(ref SharedRes.Count);
Console.WriteLine(Thrd.Name + " Count = " + SharedRes.Count);
}
}
}
class InterlockedDemo { static void Main() {
// Сконструировать два потока.
IncThread mtl = new IncThread("Инкрементирующий Поток"); DecThread mt2 = new DecThread("Декрементирующий Поток");
mtl.Thrd.Join(); mt2.Thrd.Join();
}
}
Классы синхронизации, внедренные в версии .NET Framework 4.0
Рассматривавшиеся ранее классы синхронизации, в том числе Semaphore и AutoResetEvent, были доступны в среде .NET Framework, начиная с версии 1.1.
Таким образом, эти классы образуют основу поддержки синхронизации в среде .NET Framework. Но после выпуска версии .NET Framework 4.0 появился ряд новых альтернатив этим классам синхронизации. Все они перечисляются ниже.
Класс
Назначение
Barrier
Вынуждает потоки ожидать появления всех остальных пото
ков в указанной точке, называемой барьерной
CountdownEvent
Выдает сигнал, когда обратный отсчет завершается
ManualResetEventSlim
Это упрощенный вариант класса ManualResetEvent
semaphoreslim
Это упрощенный вариант класса Semaphore
Если вам понятно, как пользоваться основными классами синхронизации, описанными ранее в этой главе, то у вас не должно возникнуть затруднений при использовании их новых альтернатив и дополнений.
Прерывание потока
Иногда поток полезно прервать до его нормального завершения. Например, отладчику может понадобиться прервать вышедший из-под контроля поток. После прерывания поток удаляется из системы и не может быть начат снова.

