Dies ist eine Detailfrage für C#.C# Thread Sicherheit mit get/set
Angenommen, ich eine Klasse mit einem Gegenstand haben, und das Objekt wird durch eine Sperre geschützt:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
return property;
}
set {
property = value;
}
}
ich ein Abrufthread diese Eigenschaft abfragen zu können, wollen. Ich möchte auch, dass der Thread die Eigenschaften dieses Objekts gelegentlich aktualisiert, und manchmal kann der Benutzer diese Eigenschaft aktualisieren, und der Benutzer möchte diese Eigenschaft sehen können.
Blockiert der folgende Code die Daten ordnungsgemäß?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
lock (mLock){
return property;
}
}
set {
lock (mLock){
property = value;
}
}
}
von ‚richtig‘, was ich meine ist, wenn ich
MyProperty.Field1 = 2;
oder was auch immer, wird anrufen will das Feld gesperrt werden, während ich das Update? Ist die Einstellung, die durch den Operator equals im Bereich der Funktion 'get' vorgenommen wird, oder wird die Funktion 'get' (und damit die Sperre) zuerst beendet und dann die Einstellung und dann 'set' aufgerufen und damit umgangen das Schloss?
Edit: Da dies offenbar nicht den Trick tun wird, was wird? Muss ich etwas wie tun:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
MyObject tmp = null;
lock (mLock){
tmp = property.Clone();
}
return tmp;
}
set {
lock (mLock){
property = value;
}
}
}
, die mehr oder weniger nur dafür sorgt, dass ich nur Zugriff auf eine Kopie haben, dass heißt, wenn ich zwei Threads haben waren nennen zugleich ‚get‘, Sie würden jeweils mit dem gleichen Wert von Field1 beginnen (richtig?). Gibt es eine Möglichkeit, Lese- und Schreibsperren für eine Eigenschaft auszuführen, die Sinn macht? Oder sollte ich mich darauf beschränken, Teile von Funktionen und nicht die Daten selbst zu sperren?
Nur so, dass dieses Beispiel sinnvoll ist: MyObject ist ein Gerätetreiber, der Status asynchron zurückgibt. Ich sende Befehle über eine serielle Schnittstelle, und dann reagiert das Gerät auf diese Befehle in seiner eigenen süßen Zeit. Im Moment habe ich einen Thread, der ihn nach seinem Status abfragt ("Bist du noch da? Kannst du Befehle annehmen?"), Ein Thread, der auf Antworten auf dem seriellen Port wartet ("Habe Status String 2, alles ist gut")), und dann der UI-Thread, der andere Befehle ("Benutzer möchte, dass Sie dies tun.") und sendet die Antworten vom Treiber ("Ich habe gerade die Sache gemacht, jetzt die UI damit aktualisieren"). Deshalb möchte ich das Objekt selbst und nicht die Felder des Objekts sperren. das wäre eine große Anzahl von Sperren, a und b, nicht jedes Gerät dieser Klasse hat das gleiche Verhalten, nur allgemeines Verhalten, also müsste ich viele individuelle Dialoge programmieren, wenn ich die Sperren individualisierte.
Einverstanden. Ich habe eine Beispiellösung für das, was Sie als Antwort auf eine Singleton Frage fragen http://stackoverflow.com/questions/7095/is-the-c-static-constructor-thread-safe/7105#7105 – Zooba
ja, ich ' Ich werde wahrscheinlich mit dem Sperren des Objekts gehen, wie Sie beschrieben haben. Vielen Dank. – mmr
Guter Punkt, aber wenn er eine 'MyProperty' namens' p' hätte und zwei Threads gleichzeitig aufruft: 'p = new MyObject (12)' und 'p = new MyObject (5)' dann würde * dieser * Zugriff synchronisiert werden . Allerdings würde das 'Field1'-Mitglied niemals gesperrt werden. Ich bin mir ziemlich sicher, dass du das sagst, ich versuche es nur für mich selbst zu verstehen. – Snoopy