为什么 BCL 中没有 AutoResetEventSlim?
为什么 BCL 中没有 AutoResetEventSlim
类?
可以使用ManualResetEventSlim来模拟吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
为什么 BCL 中没有 AutoResetEventSlim
类?
可以使用ManualResetEventSlim来模拟吗?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(3)
ManualResetEvent
和ManualResetEventSlim
均经过精心设计,以便在调用后保持有信号状态。这通常适用于与 AutoResetEvent 截然不同的场景。AutoResetEvent
使用后立即返回到无信号状态,这通常用于不同的场景。来自 AutoResetEvents 文档:然而,
ManualResetEvent
(和Slim
)通常用于以下场景:由于 AutoResetEvent 最常用于多个线程共享资源的场景,因此等待时间通常不会非常短。然而,
ManualResetEventSlim
实际上仅适用于您提前知道等待时间非常短的情况。如果您的等待时间不会很短,那么您应该使用ManualResetEvent
。有关详细信息,请参阅有关MRE 和 MRES 之间的差异的文档。当您的等待时间较长时(这将是
AutoResetEvent
的正常情况),“精简”版本实际上更糟糕,因为它会恢复为使用等待句柄。ManualResetEvent
andManualResetEventSlim
both are designed so that they remained signaled after calling. This is typically for a very different scenario thanAutoResetEvent
.AutoResetEvent
immediately returns to the unsignaled state after usage, which is typically used for a different set of scenarios. From AutoResetEvents documentation:ManualResetEvent
(andSlim
) are typically used, however, for a scenario where: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 useManualResetEvent
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.我也被这个事实困扰了。
但是,您似乎可以使用简单的 AutoResetEvent(Slim) "noreferrer">
SemaphoreSlim
具有特殊配置:在 构造函数,第一个参数定义了信号量:
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 simpleSemaphoreSlim
with a special configuration: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. Sonew AutoResetEvent( true )
translates tonew SemaphoreSlim( 1, 1 )
andnew AutoResetEvent( false )
translates tonew 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 anAutoResetEvent
.One other nice thing about the
SemaphoreSlim
is that with the newasync
/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.
引用微软的 Josh Phillips (原始在这里):
扩展评论:您可以只使用手动事件,并确保在等待后始终重置它。
如果等待和重置之间的微小延迟导致了问题,那么无论如何都可能存在根本性问题。例如,如果有多个消费者,而您应该只让其中一个通过,那么事件可能不是完成这项工作的正确工具,您应该考虑
SemaphoreSlim
甚至只是原始的Monitor< /代码>。
To quote Microsoft's Josh Phillips (original here):
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 rawMonitor
.