Что означает выходной контекст для WaitHandle.WaitOne? - PullRequest
12 голосов
/ 19 октября 2011

Я пытаюсь использовать мьютекс для защиты доступа к некоторому оборудованию из нескольких потоков, но я не совсем понимаю, что означает / делает параметр exitContext:

public virtual bool WaitOne (
    int millisecondsTimeout,
    bool exitContext
)

Документы говорят:

exitContext - true для выхода из домена синхронизации для контекста до ожидания (если в синхронизированном контексте) и повторного получения его после; в противном случае неверно .

... но что это на самом деле означает и каковы последствия установки его в значение true или false? На данный момент я установил значение true, и, похоже, код работает, но я нервничаю, что не до конца понимаю, что у него под капотом!

Ответы [ 2 ]

14 голосов
/ 19 октября 2011

Раздел «Замечания» на странице MSDN выглядит, конечно, как полный гадкий словарь.Контексты выполнения - это скрытая деталь реализации в .NET.Я просто расскажу вам, что я изменил, спроектировав его, но не смог полностью его зафиксировать.

Аргумент exitContext имеет значение только в сценариях удаленного взаимодействия.Передав true , вы разрешаете приостановку текущего вызова и маршалинг другого вызова от клиента к серверу.Вы бы сделали это для повышения пропускной способности, выбирая true только тогда, когда ожидаете, что вызов WaitOne () займет некоторое время.Точные последствия этого, однако, не очевидны для меня и не задокументированы, где я знаю.Перегрузка WaitOne () (без тайм-аута) всегда проходит false , что, к сожалению, немного напрягает мое объяснение.

Побочным эффектом этого метода является то, что Microsoft так плохо понимает, что Microsoftрешили нарушить обратную совместимость в .NET 2. Они добавили перегрузку WaitOne (int) в пакет обновления 2. В качестве аргумента exitContext передается значение false.Это вызвало много беспорядков, программисты начали использовать его, а затем обнаружили, что их программа перестала работать при запуске в версии .NET до SP2.Уч.

5 голосов
/ 19 октября 2011

Это также объясняет далее внизу страницы под примечаниями , что:

Примечания по выходу из контекста

Параметр exitContext не действует, если только метод WaitOneвызывается из контекста, не управляемого по умолчанию.Это может произойти, если ваш поток находится внутри вызова экземпляра класса, производного от ContextBoundObject.Даже если вы в настоящее время выполняете метод для класса, который не является производным от ContextBoundObject, например String, вы можете находиться в контексте, отличном от значения по умолчанию, если ContextBoundObject находится в вашем стеке в текущем домене приложения.выполняется в контексте не по умолчанию, указание true для exitContext заставляет поток выйти из управляемого контекста не по умолчанию (то есть перейти к контексту по умолчанию) перед выполнением метода WaitOne.Поток возвращается в исходный контекст не по умолчанию после завершения вызова метода WaitOne.

Это может быть полезно, когда у привязанного к контексту класса есть SynchronizationAttribute.В этом случае все вызовы членов класса автоматически синхронизируются, и домен синхронизации является всем телом кода для класса.Если код в стеке вызова члена вызывает метод WaitOne и указывает значение true для exitContext, поток выходит из домена синхронизации, позволяя потоку, заблокированному при вызове любого члена объекта, продолжить работу.Когда метод WaitOne возвращается, поток, который сделал вызов, должен дождаться повторного входа в домен синхронизации.

...