Questa è una domanda di dettaglio per C#.C# sicurezza filo con get/set
Supponiamo che io ho una classe con un oggetto e l'oggetto è protetto da una serratura:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
return property;
}
set {
property = value;
}
}
Voglio un thread di polling per essere in grado di interrogare quella proprietà. Desidero inoltre che il thread aggiorni le proprietà di tale oggetto occasionalmente e talvolta l'utente può aggiornare tale proprietà e l'utente desidera poter vedere tale proprietà.
Il seguente codice blocca correttamente i dati?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
lock (mLock){
return property;
}
}
set {
lock (mLock){
property = value;
}
}
}
Con 'correttamente', quello che voglio dire è, se voglio chiamare
MyProperty.Field1 = 2;
o qualsiasi altra cosa, sarà il campo bloccato mentre faccio l'aggiornamento? L'impostazione eseguita dall'operatore di uguale all'interno dell'ambito della funzione 'get', o la funzione 'get' (e quindi il lock), terminano prima, e quindi l'impostazione, e quindi 'set' viene chiamato, bypassando così la serratura?
Modifica: Dal momento che questo a quanto pare non farà il trucco, quale sarà? Ho bisogno di fare qualcosa di simile:
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;
}
}
}
che più o meno fa solo in modo che io ho solo l'accesso a una copia, il che significa che se dovessi avere due thread chiamano un 'get', allo stesso tempo, inizierebbero ciascuno con lo stesso valore di Field1 (giusto?). C'è un modo per leggere e scrivere su una proprietà che ha senso? O dovrei limitarmi a bloccare sezioni di funzioni piuttosto che i dati stessi?
Proprio questo esempio ha senso: MyObject è un driver di periferica che restituisce lo stato in modo asincrono. Gli mando i comandi tramite una porta seriale, e poi il dispositivo risponde a quei comandi nel suo momento dolce. In questo momento, ho un thread che lo interroga per il suo stato ("Sei ancora lì? Puoi accettare i comandi?"), Un thread che aspetta risposte sulla porta seriale ("Just got status string 2, tutto va bene"), quindi il thread dell'interfaccia utente che accetta altri comandi ("Utente desidera che tu faccia questa cosa.") e posta le risposte dal driver ("Ho appena fatto la cosa, ora aggiorno l'interfaccia utente con quello"). Ecco perché voglio bloccare l'oggetto stesso, piuttosto che i campi dell'oggetto; sarebbe un numero enorme di blocchi, a, eb, non tutti i dispositivi di questa classe hanno lo stesso comportamento, solo un comportamento generale, quindi dovrei codificare molte finestre di dialogo individuali se ho individuato i blocchi.
concordato. Ho fornito una soluzione di esempio per ciò che stai chiedendo in risposta a una domanda Singleton http://stackoverflow.com/questions/7095/is-the-c-static-constructor-thread-safe/7105#7105 – Zooba
sì, io ' Probabilmente andremo a bloccare l'oggetto come hai descritto. Grazie. – mmr
Buon punto, tuttavia se ha avuto un 'MyProperty' chiamato' p' e ha chiamato due thread contemporaneamente: 'p = new MyObject (12)' e 'p = new MyObject (5)' allora * questo * accesso sarebbe stato sincronizzato . Comunque il membro 'Field1' non * resterà * mai bloccato. Sono abbastanza sicuro che questo è quello che stai dicendo, solo cercando di capirlo da solo. – Snoopy