Frage

In meiner Anwendung habe ich ein Formular, das Synchronisierungsprozess gestartet und für Reihe von Gründen mag ich nur eine Synchronisation ermöglichen, zu einem Zeitpunkt, zu laufen. Also habe ich ein statisches Bool Feld zu meiner Form hinzugefügt anzeigt, ob die Synchronisierung im Gang ist und habe eine Sperre dieses Feld auf true gesetzt, wenn es nicht bereits eingestellt wurde, so dass erste Thread-Synchronisierung starten könnte, aber wenn es all anderen Thread ausgeführt wird, wird versuchen, es zu starten wird beendet.

Mein Code ist so etwas wie folgt aus:

internal partial class SynchronizationForm : Form
{
    private static volatile bool workInProgress;

    private void SynchronizationForm_Shown(object sender, EventArgs e)
    {
        lock (typeof(SynchronizationForm))
        {
            if (!workInProgress)
            {
                workInProgress = true;
            }
            else
            {
                this.Close();
            }
        }
    }
}

Das funktioniert gut, aber wenn ich Code-Analyse laufe auf meinem Projekt, das ich erhalte die folgende Warnmeldung an:

  

CA2002: Microsoft.Reliability: 'SynchronizationForm.SynchronizationForm_Shown (Objekt, EventArgs)' Sperren auf einer Referenz des Typs 'Typ'. Ersetzen Sie diese mit einem Schloss gegen ein Objekt mit starken Identität.

Kann jemand mir erklären, was mit meinem Code falsch und wie kann ich verbessern sie die Warnung weg zu machen. Was bedeutet es, das Objekt hat eine starke Identität?

War es hilfreich?

Lösung

Was falsch ist, ist, dass man auf etwas öffentlich (typeof(SynchronizationForm)) sind Sperren, die aus dem Code überall zugänglich ist und wenn einige andere Thread Sperren auf derselben Sache einen Deadlock zu bekommen. Im Allgemeinen ist es eine gute Idee, nur auf private statischen Objekte zu sperren:

private static object _syncRoot = new object();
...
lock (_syncRoot) 
{

}

Dies garantiert Ihnen, dass es nur SynchronizationForm ist, der die Sperre besitzen könnte.

Andere Tipps

Aus der MSDN Erklärung der Regel

  

Ein Objekt wird gesagt, eine schwache Identität haben, wenn es direkt über Anwendungsdomänengrenzen hinweg zugreifen kann. Ein Thread, der eine Sperre für ein Objekt zu erwerben versucht, die eine schwache Identität wird von einem zweiten Thread in einem anderen Anwendungsdomäne blockiert werden kann, der eine Sperre auf dem gleiche Objekt hat.

Da man nicht unbedingt vorhersagen kann, was andere AppDomain sperrt könnte nehmen, und da solche Schlösser rangieren könnten müssen und wären dann teuer sein, diese Regel macht Sinn für mich.

Das Problem ist, dass typeof (SynchronizationForm) ist keine privates Sperrobjekt, was bedeutet, dass jedes anderes Stück Code könnte es benutzen zu erfassen, die in einer Sackgasse führen könnte. Zum Beispiel, wenn ein anderer Code tut dies:

var form = new SynchronizationForm();
lock(typeof(SynchronizationForm))
{
    form.SomeMethodThatCausesSynchronizationForm_ShownToBeCalled();
}

Dann Deadlock auftreten wird. Stattdessen sollten Sie ein eigenes Sperrobjekt in der SynchronizationForm Klasse delcare und Sperre auf, dass statt.

  

Das System.Type Objekt einer Klasse kann in geeigneter Weise als die gegenseitigen Ausschlusssperre für statische Methoden der Klasse verwendet werden.

Quelle: http://msdn.microsoft. com / en-us / library / aa664735 (VS.71) aspx

Doug Antwort hinzuzufügen, was Sie hier haben, ist ein Verriegelungsmechanismus, der nur in statischen Methoden verwendet werden soll, in einer Instanzmethode verwendet wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top