Как проверить состояние блокировки AutoResetEvent или ManualResetEvent в C #? - PullRequest
4 голосов
/ 17 февраля 2012

Можно ли проверить состояние блокировки для C # System.Threading.AutoResetEvent или System.Threading.ManualResetEvent перед вызовом WaitOne ()?

Ответы [ 3 ]

5 голосов
/ 17 февраля 2012

EventWaitHandle не имеет «состояния блокировки». Он установлен или сброшен, больше ничего. И нет, вы не можете проверить это каким-либо иным способом, кроме как путем вызова WaitOne ().

Вы можете передать 0 для аргумента тайм-аута, чтобы избежать блокировки. Это часто очень плохая идея, потому что она ничего не говорит о состоянии события после возврата вызова WaitOne (). Это могло бы изменить наносекунду после этого. Это вызывает очень неприятную ошибку, называемую «многопоточность». Гейзенбаг.

1 голос
/ 17 февраля 2012

Использование

public virtual bool WaitOne(
    TimeSpan timeout
)

с таймаутом 0. Согласно MSDN он немедленно вернет состояние WaitHandle.

0 голосов
/ 23 октября 2013

У меня был тот же вопрос, на самом деле я просто собирал демонстрационное приложение. (Новичок в EventWaitHandle.)

Вот как я решил проблему (в VB.NET):

Module Module1

Dim ewh As Threading.EventWaitHandle

Sub Main()
  ewh = New Threading.EventWaitHandle(False, Threading.EventResetMode.ManualReset)
  ' Do other work.
End Sub

Sub checkBlockStatus()

  ewh.WaitOne()

End Sub

Function isEwhBlocked() As Boolean

  Dim testEwhBlock As New Threading.Thread(AddressOf checkBlockStatus)
  testEwhBlock.Start()
  Threading.Thread.Sleep(1000)
  If testEwhBlock.ThreadState <> Threading.ThreadState.Stopped Then
     ' It's OK to use abort here because I don't care what happens to the thread.
     testEwhBlock.Abort()
     Return True
  Else
     Return False
  End If
  testEwhBlock = Nothing

End Function
End Module

В любой момент, когда вам нужно проверить состояние блокировки этого экземпляра, просто сделайте это:

if (isEwhBlocked()) Then
  ' This means the block is on.
else
  ' No block.
End If

Итак, нет, вы не можете ДЕЙСТВИТЕЛЬНО выяснить, что заблокировано, перед вызовом WaitOne (), но вы можете запустить его способом ASync, который не позволит ему захватить ваш основной поток. Возможно, вы могли бы также немного уменьшить значение сна, если это слишком долго ждать.

Очевидно, что если вам нужно проверить несколько блоков, функция становится немного более сложной (или вам нужно создать больше из них), но это демонстрирует основной принцип. Я также проверил это как автоматический сброс, и он не работает так же хорошо. Поскольку обработчик находится в режиме автоматического сброса, после вызова метода для проверки блока он сбрасывает и блокирует другой поток. Так что, если вы можете запустить в ManualReset, это может сработать для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...