gpt4 book ai didi

c# - 急切地处理 ManualResetEvent

转载 作者:太空狗 更新时间:2023-10-29 21:55:33 25 4
gpt4 key购买 nike

我有一个类允许其他线程等待,直到它使用 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();
}

最佳答案

我在您的代码中看到的最重要的事情是 waiter 的设置至 null打电话后 Dispose .我在我负责的非托管接口(interface)上有大量托管包装器,当我迁移到 .Net 4.0 时,这种做法在某些线程场景中又回来咬我了。

关于 ManualResetEventSlim.Dispose 的 MSDN 信息表明它不是线程安全的,但是,查看其实际实现,多次调用 Dispose 并没有什么危险。来自多个线程。此外,IDisposable 的实现应该非常能够容忍多次调用(如其设计指南中所指定)。

我玩过的一个想法是重新排序 OnCompleted稍微允许读者在完成后不久订阅:

//This method is called exactly once.
protected internal virtual void OnCompleted(string result) {
Result = result;
isCompleted = true;

waiter.Set();
Thread.MemoryBarrier();
if (waitingCount == 0) {
waiter.Dispose();
}
}

<罢工>

关于c# - 急切地处理 ManualResetEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6266597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com