为什么 BCL 中没有 AutoResetEventSlim?

发布于 2024-12-17 09:44:24 字数 91 浏览 1 评论 0 原文

为什么 BCL 中没有 AutoResetEventSlim 类?

可以使用ManualResetEventSlim来模拟吗?

Why isn't there an AutoResetEventSlim class in BCL?

Can it be simulated using ManualResetEventSlim?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

段念尘 2024-12-24 09:44:25

ManualResetEventManualResetEventSlim 均经过精心设计,以便在调用后保持有信号状态。这通常适用于与 AutoResetEvent 截然不同的场景。

AutoResetEvent 使用后立即返回到无信号状态,这通常用于不同的场景。来自 AutoResetEvents 文档:

通常,当线程需要独占访问资源时,您可以使用此类。

然而,ManualResetEvent(和Slim)通常用于以下场景:

此通信涉及一项任务,一个线程必须先完成该任务,然后其他线程才能继续。

由于 AutoResetEvent 最常用于多个线程共享资源的场景,因此等待时间通常不会非常短。然而,ManualResetEventSlim 实际上仅适用于您提前知道等待时间非常短的情况。如果您的等待时间不会很短,那么您应该使用ManualResetEvent。有关详细信息,请参阅有关MRE 和 MRES 之间的差异的文档。

当您的等待时间较长时(这将是 AutoResetEvent 的正常情况),“精简”版本实际上更糟糕,因为它会恢复为使用等待句柄。

ManualResetEvent and ManualResetEventSlim both are designed so that they remained signaled after calling. This is typically for a very different scenario than AutoResetEvent.

AutoResetEvent immediately returns to the unsignaled state after usage, which is typically used for a different set of scenarios. From AutoResetEvents documentation:

Typically, you use this class when threads need exclusive access to a resource.

ManualResetEvent (and Slim) are typically used, however, for a scenario where:

this communication concerns a task which one thread must complete before other threads can proceed.

Since AutoResetEvent is most commonly used in scenarios where there are multiple threads sharing a resource, wait times typically would not be extremely short. ManualResetEventSlim, however, is really only intended when you know, in advance, the wait time is very short. If your wait time is not going to be very short, then you should use ManualResetEvent instead. See the documentation on the difference between MRE and MRES for details.

When your wait times are longer (which would be the normal scenario with AutoResetEvent), the "slim" version is actually worse, as it reverts to using a wait handle.

菊凝晚露 2024-12-24 09:44:25

我也被这个事实困扰了。
但是,您似乎可以使用简单的 AutoResetEvent(Slim) "noreferrer">SemaphoreSlim 具有特殊配置:

SemaphoreSlim Lock = new SemaphoreSlim( 1, 1 );

构造函数,第一个参数定义了信号量:1表示一个线程可以进入,0表示信号量有要先被释放。因此,new AutoResetEvent( true ) 转换为 new SemaphoreSlim( 1, 1 ) ,而 new AutoResetEvent( false ) 转换为 new SemaphoreSlim( 0, 1) 分别。

第二个参数定义可以同时进入信号量的最大线程数。将其设置为 1 使其行为类似于 AutoResetEvent

SemaphoreSlim 的另一件好事是,通过 4.5 中新的 async/await 模式,该类收到了 .WaitAsync() 方法 可以等待。因此,在这种情况下不再需要手动创建可等待的等待原语。

希望这有帮助。

I was bugged by this fact as well.
However, it appears that you can simulate an AutoResetEvent(Slim) using a simple SemaphoreSlim with a special configuration:

SemaphoreSlim Lock = new SemaphoreSlim( 1, 1 );

In the constructor, the first parameter defines the initial state of the semaphore: 1 means that one thread may enter, 0 that the semaphore has to be released first. So new AutoResetEvent( true ) translates to new SemaphoreSlim( 1, 1 ) and new AutoResetEvent( false ) translates to new SemaphoreSlim( 0, 1 ) respectively.

The second parameter defines the maximum number of threads that may enter the semaphore concurrently. Setting it to 1 lets it behave like an AutoResetEvent.

One other nice thing about the SemaphoreSlim is that with the new async/await pattern in 4.5 the class has received a .WaitAsync() method which can be awaited. So there is no need to manually create an awaitable wait primitive in this case any more.

Hope this helps.

扭转时空 2024-12-24 09:44:25

引用微软的 Josh Phillips (原始在这里):

至于AutoResetEventSlim..是否有您需要它的场景?
说实话,创建 AutoResetEvent 非常困难,而且
用例非常有限,因此我们优先考虑其他地方的工作。
如果您确实需要一个,我很想听听,所以我们
可以考虑创建一个!

扩展评论:您可以只使用手动事件,并确保在等待后始终重置它。

如果等待和重置之间的微小延迟导致了问题,那么无论如何都可能存在根本性问题。例如,如果有多个消费者,而您应该只让其中一个通过,那么事件可能不是完成这项工作的正确工具,您应该考虑 SemaphoreSlim 甚至只是原始的 Monitor< /代码>。

To quote Microsoft's Josh Phillips (original here):

As for AutoResetEventSlim.. is there a scenario for which you need it?
Truth be told, creating an AutoResetEvent is quite difficult and the
use cases are very limited so we prioritized our efforts elsewhere
.
If there's a real need for you to have one, I'd love to hear it so we
could consider creating one!

To expand on the comment: you can just use a manual event and make sure to always reset it after waiting.

If that small delay between waiting and resetting is causing problems, there's probably a fundamental issue somewhere anyway. For instance, if there are multiple consumers and you should only let one through, maybe an event isn't the right tool for the job and you should consider SemaphoreSlim or even just the raw Monitor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文