【发布时间】:2011-06-08 01:44:28
【问题描述】:
我有一个类允许其他线程等待,直到它使用ManualResetEventSlim 完成操作。 (操作通常很简短)
这个类没有明确的生命周期,所以没有一个地方可以让我轻松关闭事件。
相反,我想在事件完成后立即关闭它——一旦它发出信号,并且在任何等待线程唤醒之后。
出于性能原因,我不想使用锁。
这段代码是线程安全的吗?可以做得更快吗?
volatile bool isCompleted;
volatile int waitingCount;
ManualResetEventSlim waiter = new ManualResetEventSlim();
//This method is called on any thread other than the one that calls OnCompleted
public void WaitForCompletion() {
if (isCompleted)
return;
Interlocked.Increment(ref waitingCount);
Thread.MemoryBarrier();
if (!isCompleted)
waiter.Wait();
if (0 == Interlocked.Decrement(ref waitingCount)) {
waiter.Dispose();
waiter = null;
}
return;
}
//This method is called exactly once.
protected internal virtual void OnCompleted(string result) {
Result = result;
isCompleted = true;
Thread.MemoryBarrier();
if (waitingCount == 0) {
waiter.Dispose();
waiter = null;
} else
waiter.Set();
}
【问题讨论】:
-
进一步看,如果同时调用这两种方法,我认为它可能会双重处理服务员。
-
在所有符合
IDisposable的实现中多次调用Dispose是安全的。 -
@six:是的,但我也是
nulling 变量。但是,这可能不是必需的。 -
@SLaks:我会避免
nulling,我发现它没有帮助,最终会在某个时候引入一个奇怪的角落案例。 -
另外,
ManualResetEventSlim.Dispose不是线程安全的; 一次调用两次可能不太合适。
标签: c# .net thread-safety