Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


События и безопасность потоков




В предыдущем разделе я продемонстрировал, как компилятор C# добавляет атрибут [Methodlmpl(MethodlmplOptionsSynchronized)] в методы add или remove события. Задача этого атрибута — гарантировать, что только методы add или remove будут выполняться в типе при обработке статического члена-события. Эта синхронизация потоков необходима для обеспечения целостности списка объектов-делегатов. Однако надо иметь в виду, что есть много проблем, возникающих из-за способа реализации этой синхронизации потоков в CLR.

При применении атрибута Methodlmpl к экземплярному (нестатическому) методу среда CLR использует сам объект в качестве блокировки, предназначенной для синхронизации потоков. Это означает, что, если в классе определено много событий, все методы add или remove используют одну блокировку, а это отрицательно сказывается на масштабируемости, если есть несколько потоков, одновременно регистрирующихся и отказывающихся от регистрации на подписку на различные события. Это очень редкая ситуация, и в большинстве случаев описанная проблема себя не проявляет. Тем не менее правила синхронизации потоков требуют, чтобы методы не использовали для блокировки собственный объект, потому что блокировка открыта и доступна любому внешнему коду. Это означает, что любой может написать код, блокирующий объект и, в принципе, способный вызвать взаимную блокировку. Если требуется обеспечить защиту объекта от таких проблем и сделать его работу надежнее, для блокировки следует использовать другой объект. Как это сделать, я расскажу в следующем разделе.

При применении атрибута [Methodlmpl(MethodlmplOptionsSynchronized)] к статическому методу среда CLR использует объект-тип в качестве блокировки, предназначенной для синхронизации потоков. И это означает, что, если в классе определено много событий, все методы afiW или remove используют одну блокировку и это отрицательно сказывается на масштабируемости, если есть несколько потоков одновременно, регистрирующихся и отказывающихся от регистрации на подписку на различные события. И снова, такая ситуация случается нечасто.

Однако есть значительно более серьезная проблема: правила синхронизации потоков требуют, чтобы методы не использовали для блокировки собственный объект, потому что блокировка открыта и доступна любому внешнему коду. В добавок, в CLR есть «жучок», связанный с загрузкой без привязки к конкретному домену приложения. В такой ситуации блокировка совместно применяется всеми доменами AppDomain, использующими тип, что позволяет коду одного домена нарушить работу кода другого домена. В действительности, компилятор С# должен был бы делать совсем другое для обеспечения безопасности потоков при работе методов add и remove. В следующем разделе я расскажу о механизме, который можно использовать для устранения недостатка компилятора С#.

С# и CLR позволяют определить значимый тип (структуру) с одним или несколькими (нестатическими) членами-событиями, но нужно иметь в виду, что при этом компилятор C# не обеспечивает никакой безопасности потоков. Причина в том, что у неупакованных значимых типов нет связанного с ними объекта блокировки. В сущности компилятор C# не обозначает атрибутом [MethodImpl(MethodImpl-OptionsSynchronized)] методы add и remove, потому что этот атрибут никак не повлияет на экземплярные методы значимого типа. К сожалению, нет универсального способа обеспечить безопасность потоков событий экземпляров, если они определены как члены значимого типа, поэтому рекомендуется избегать этого. Стоит заметить, что вполне допустимо (с описанными выше ограничениями) определять статические события значимого типа, так как для блокировки они используют объект-тип (а это ссылочный тип). Однако, если вас интересует по-настоящему надежное решение, рекомендую использовать механизм, описанный в следующем разделе.

 


Поделиться:

Дата добавления: 2015-04-21; просмотров: 52; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты