gpt4 book ai didi

.net - AutoResetEvent 类型是原子开关的合适选择吗?

转载 作者:行者123 更新时间:2023-11-30 23:59:08 27 4
gpt4 key购买 nike

假设我正在处理来自多个线程的大量传入数据。当满足某些条件时,我可能希望这些数据充当特定操作的触发器。然而, Action 不可重入;所以同一个触发器被快速连续触发两次应该只会导致 Action 运行一次。

使用简单的 bool指示操作当前是否正在运行的标志不是一个健壮的解决方案,因为可能会发生竞争条件,并且两个(或更多)线程最终仍可能最终并发运行相同的操作。一个 boollock当然,同步对象上的语句会起作用;但我通常更愿意尽可能避免锁定*。

目前我在这些情况下所做的是使用 AutoResetEvent 本质上是一种原子开关。代码通常如下所示:

if (conditionMet && readyForAction.WaitOne(0))
{
try
{
doAction();
}
finally
{
readyForAction.Set();
}
}

这行得通,但令我震惊的是,对于 AutoResetEvent 来说,这可能是一个不太理想的用例。类(class)。您会说这是解决此问题的合适方法,还是使用其他机制更有意义?

更新 : 作为 Jon pointed out , 使用 Monitor.TryEnter作为锁定策略(而不是简单的 lock ,我认为它大致相当于 Monitor.Enter ),真的非常简单:
if (conditionMet && Monitor.TryEnter(lockObject))
{
try
{
doAction();
}
finally
{
Monitor.Exit(lockObject);
}
}

也就是说,我非常倾向于使用 Henk's idea使用 Interlocked .这似乎很简单。

最佳答案

一个简单(且快速)的 System.Threading.Interlocked.CompareExchange() 会做。

//untested
int flag = 0;

if (conditionMet && Interlocked.CompareExchange(ref flag, 1, 0) == 0)
{
try
{
doAction();
}
finally
{
flag = 0; // no need for locking
}
}

关于.net - AutoResetEvent 类型是原子开关的合适选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3674314/

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