是否可以检查C#System.Threading.AutoResetEvent或的阻塞状态 调用WaitOne()之前的System.Threading.ManualResetEvent?
答案 0 :(得分:5)
EventWaitHandle没有“阻塞状态”。它被设置或重置,没有别的。不,你不能通过调用WaitOne()来检查其他任何方式。
您可以为超时参数传递0以避免阻塞。这通常是一个非常糟糕的主意,因为在WaitOne()调用返回后它没有说明事件的状态。之后它可能已经改变了一纳秒。这会导致一种非常讨厌的错误,称为“穿线竞赛”。一个Heisenbug。
答案 1 :(得分:1)
使用
public virtual bool WaitOne(
TimeSpan timeout
)
超时0.根据MSDN,它将立即返回WaitHandle的状态。
答案 2 :(得分:0)
我有同样的问题,真的只是构建一个演示应用程序。 (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方式运行它,以防止它占用你的主线程。如果等待的时间太长,你可能会减少睡眠值。
显然,如果你需要检查多个块,那么函数会变得有点复杂(或者你必须创建更多它们),但这证明了基本原理。我还测试了它作为AutoReset,并且它不能很好地工作。因为处理程序是自动复位的,所以一旦我调用方法来检查块,它就会重置并阻塞我的其他线程。因此,如果您可以在ManualReset中运行,这可能对您有用。