我有一个state
变量,其关注域为thread-safe
,并使用fresh
保留了ReaderWriterLockSlim
。自从我使用以来,我对所有字段的访问都得到了细化他们分别放在其他地方。
虽然可以单独访问字段,但是我还需要使几个操作原子化。在这种情况下,我是否需要额外的lock
?
我有一个状态变量,该变量已经包含thread-safe
个字段:
internal class State {
private ReaderWriterLockSlim lck = new ReaderWriterLockSlim();
private bool cmd_PopUp;
private bool cmd_Shutdown;
private bool cmd_Delay;
public bool CMD_PopUp {
get {
try {
this.lck.EnterReadLock();
return this.cmd_PopUp;
} finally {
this.lck.ExitReadLock();
}
}
set {
try {
this.lck.EnterWriteLock();
this.cmd_PopUp = value;
} finally {
this.lck.ExitWriteLock();
}
}
}
//same goes for the other booleans
}
我已经具有线程安全性,并且我确保线程从内存中读取而不是从本地缓存中读取。但是,我需要执行多个原子操作。
原子操作
public async Task Run(State state)
{
while(true)
{
//do i need a lock here
if (state.CMD_Delay) {
state.CMD_Delay = false;
state.CMD_PopUp = false;
//end of potential lock ?
} else if (state.CMD_Shutdown) { //same here
state.CMD_PopUp = false;
state.CMD_Shutdown = false;
await SomeAction();
}
}
}
正如您在我的while
中看到的那样,我有一个if-else
,在这里我需要使操作组成为原子操作。应该使用额外的lock
还是有其他轻量级解决方案?
答案 0 :(得分:1)
重新使用您现有的锁对我来说最有意义:
internal class State
{
...
public void SetDelayState()
{
try {
this.lck.EnterWriteLock();
this.cmd_Delay = false;
this.cmd_PopUp = false;
} finally {
this.lck.ExitWriteLock();
}
}
public void SetShutdownState()
{
try {
this.lck.EnterWriteLock();
this.cmd_PopUp = false;
this.cmd_Shutdown = false;
} finally {
this.lck.ExitWriteLock();
}
}
}
换句话说,将所有原子操作移为您的State
类型的成员。
侧面说明:您几乎可以肯定不需要读/写锁。读卡器/写卡器锁只能在以下条件的所有为真时使用:
如果其中的任何个都不正确,那么lock
是更好的选择。