为什么BCL中没有AutoResetEventSlim
课程?
可以使用ManualResetEventSlim
进行模拟吗?
答案 0 :(得分:27)
ManualResetEvent
和ManualResetEventSlim
都经过精心设计,以便在致电后保持信号状态。这通常与AutoResetEvent
非常不同。
AutoResetEvent
在使用后立即返回无信号状态,通常用于不同的场景集。来自AutoResetEvents文档:
通常,当线程需要对资源的独占访问时,可以使用此类。
ManualResetEvent
(和Slim
)通常用于以下情况:
此通信涉及一个线程必须完成的任务,然后其他线程才能继续。
由于AutoResetEvent
最常用于共享资源的多个线程的情况,因此等待时间通常不会非常短。但是,ManualResetEventSlim
实际上只是在事先知道等待时间很短的情况下才有意。如果您的等待时间不会很短,那么您应该使用ManualResetEvent
代替。有关详细信息,请参阅difference between MRE and MRES上的文档。
当您的等待时间较长时(这将是AutoResetEvent
的正常情况),"苗条"版本实际上更糟糕,因为它恢复使用等待句柄。
答案 1 :(得分:13)
我也被这个事实所困扰。 但是,您似乎可以使用具有特殊配置的简单SemaphoreSlim来模拟AutoResteEvent(Slim):
SemaphoreSlim Lock = new SemaphoreSlim( 1, 1 );
第一个参数(http://msdn.microsoft.com/en-us/library/dd270891(v=vs.110).aspx)定义信号量的初始状态:1表示一个线程可以输入,0表示必须首先释放信号量。因此a = new AutoResetEvent( true )
转换为= new SemaphoreSlim( 1, 1 )
和a = new AutoResetEvent( false )
分别转换为= new SemaphoreSlim( 0, 1 )
。
第二个参数定义可以同时进入信号量的最大线程数。将其设置为1可使其表现得像AutoResetEvent
。
SemaphoreSlim的另一个好处是,使用4.5中的新async / await模式,该类已经收到了一个可以等待的.WaitAsync()
方法。因此,不再需要在这种情况下手动创建一个等待的等待原语。
希望这有帮助。