如何在C#中检查AutoResetEvent或ManualResetEvent的阻塞状态?
是否可以检查 C# System.Threading.AutoResetEvent 的阻塞状态或 调用 WaitOne() 之前的 System.Threading.ManualResetEvent ?
Is it possible to check the blocking state for C# System.Threading.AutoResetEvent or
System.Threading.ManualResetEvent before calling WaitOne() ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
EventWaitHandle 没有“阻塞状态”。它被设置或重置,没有别的。不,除了调用 WaitOne() 之外,您无法通过任何其他方式进行检查。
您可以为超时参数传递 0 以避免阻塞。这通常是一个非常糟糕的主意,因为它没有说明 WaitOne() 调用返回后事件的状态。之后它可能会改变一纳秒。这会导致一种非常令人讨厌的错误,称为“线程竞争”。一只海森虫。
An EventWaitHandle doesn't have a "blocking state". It is set or reset, nothing else. And no, you cannot check that any other way than by calling WaitOne().
You can pass a 0 for the time-out argument to avoid blocking. That's often a very bad idea because it says nothing about the state of the event after the WaitOne() call returns. It might have changed a nanosecond after that. This causes a very nasty kind of bug called "threading race". A Heisenbug.
使用
超时 0。根据 MSDN,它将立即返回 WaitHandle 的状态。
Use
with timeout 0. According to MSDN it will return the state of the WaitHandle immediately.
我有同样的问题,实际上只是构建一个演示应用程序。 (EventWaitHandle 的新手。)
这就是我解决问题的方法(在 VB.NET 中):
在任何时候您需要检查该实例的阻塞状态,只需执行以下操作:
所以,不,您无法真正弄清楚在调用 WaitOne() 之前被阻止的内容,但您可以以异步方式运行它,以防止它占用主线程。如果等待时间太长,您也可以稍微降低睡眠值。
显然,如果您需要检查多个块,该函数会变得有点复杂(或者您必须创建更多块),但这演示了基本原理。我还测试了它作为自动重置,但效果不太好。因为处理程序处于自动重置状态,所以一旦我调用该方法来检查块,它就会重置并阻止我的其他线程。因此,如果您可以在 ManualReset 中运行,这可能对您有用。
I had the same question, really just building a demo app. (Newbie to EventWaitHandle.)
This is how I solved the problem (in VB.NET):
At any point that you need to check the blocking status of that instance, just do this:
So, no, you can't REALLY figure out what is blocked before calling WaitOne(), but you can run it in an ASync way that prevents it from seizing your main thread. You could probably reduce the sleep value quite a bit as well, if that is too long to wait.
Obviously, if you need to check on multiple blocks, the function gets a tad bit more complex (or you have to create more of them), but this demonstrates the basic principle. I also tested this as an AutoReset, and it doesn't work quite as well. Because the handler is in autoreset, once I call the method to check the block, it resets and blocks my other thread. So if you can run in ManualReset, this could work for you.