我只是想知道这个代码是否是一个开发人员(后来已经离开)是好的,我想他想避免锁定。这与仅使用直接锁定之间存在性能差异吗?
private long m_LayoutSuspended = 0;
public void SuspendLayout()
{
Interlocked.Exchange(ref m_LayoutSuspended, 1);
}
public void ResumeLayout()
{
Interlocked.Exchange(ref m_LayoutSuspended, 0);
}
public bool IsLayoutSuspended
{
get { return Interlocked.Read(ref m_LayoutSuspended) != 1; }
}
我当时认为锁定会更容易吗?它确实会被多个线程使用,因此决定使用锁定/互锁的原因。
答案 0 :(得分:13)
是的,从竞争角度到达m_LayoutSuspended
字段,您正在做的是安全的,但是,如果代码执行以下操作,则需要锁定以下原因:
if (!o.IsLayoutSuspended) // This is not thread Safe .....
{
o.SuspendLayout(); // This is not thread Safe, because there's a difference between the checck and the actual write of the variable a race might occur.
...
o.ResumeLayout();
}
一种更安全的方式,使用CompareExchange
确保没有发生竞争条件:
private long m_LayoutSuspended = 0;
public bool SuspendLayout()
{
return Interlocked.CompareExchange(ref m_LayoutSuspended, 1) == 0;
}
if (o.SuspendLayout())
{
....
o.ResumeLayout();
}
或者更好,只需使用锁。
答案 1 :(得分:10)
就个人而言,我会使用volatile布尔值:
private volatile bool m_LayoutSuspended = false;
public void SuspendLayout()
{
m_LayoutSuspended = true;
}
public void ResumeLayout()
{
m_LayoutSuspended = false;
}
public bool IsLayoutSuspended
{
get { return m_LayoutSuspended; }
}
然后,正如我最近在其他地方承认的那样,不稳定并不意味着我的想法。我怀疑这没关系:))
即使您坚持使用Interlocked
,我也会将其更改为int
...没有必要让32位系统在他们可以做的时候可能难以制作64位写入原子很容易用32位......