13 Stimmen

Interlocked verwendet, um einen booleschen Wert zu erhöhen/zu imitieren, ist dies sicher?

Ich frage mich nur, ob dieser Code, den ein Entwicklerkollege (der inzwischen gegangen ist), OK ist, ich glaube, er wollte vermeiden, eine Sperre zu setzen. Gibt es einen Leistungsunterschied zwischen diesem und nur mit einer geraden forward Sperre?

    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; }
    }

Ich habe gedacht, dass so etwas mit einem Schloss einfacher wäre? Es wird in der Tat von mehreren Threads verwendet werden, weshalb die Verwendung von Sperren/interlocked beschlossen wurde.

16voto

Pop Catalin Punkte 59610

Ja, was Sie tun, ist vom Standpunkt des Rennens aus gesehen sicher, wenn Sie die m_LayoutSuspended Eine Sperre ist jedoch aus folgendem Grund erforderlich, wenn der Code Folgendes tut:

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();
} 

Ein sicherer Weg, der die CompareExchange um sicherzustellen, dass keine Wettlaufbedingungen aufgetreten sind:

private long m_LayoutSuspended = 0;
public bool SuspendLayout()
{
    return Interlocked.CompareExchange(ref m_LayoutSuspended, 1) == 0;
}

if (o.SuspendLayout()) 
{
  ....
  o.ResumeLayout();
}

Oder besser noch, verwenden Sie einfach ein Schloss.

10voto

Jon Skeet Punkte 1325502

Ich persönlich würde einen flüchtigen Booleschen Wert verwenden:

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; }
}

Andererseits bedeutet "flüchtig", wie ich kürzlich an anderer Stelle festgestellt habe, nicht ganz das, was ich dachte. Ich vermute aber, dass dies in Ordnung ist :)

Selbst wenn Sie sich an Interlocked würde ich es in eine int ... es gibt keinen Grund, 32-Bit-Systemen das Schreiben von 64-Bit-Atomdateien zu erschweren, wenn dies mit 32-Bit-Systemen problemlos möglich ist...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X