Versione C # della parola chiave sincronizzata di java?

C # ha la sua versione della parola chiave “sincronizzata” java?

Cioè in java può essere specificato o per una funzione, un object o un blocco di codice, in questo modo:

public synchronized void doImportantStuff() { // dangerous code goes here. } 

o

 public void doImportantStuff() { // trivial stuff synchronized(someLock) { // dangerous code goes here. } } 

Primo: la maggior parte delle classi non avrà mai bisogno di essere thread-safe. Usa YAGNI : applica la sicurezza del thread solo quando sai che effettivamente lo userai (e lo testerai).

Per il materiale a livello di metodo, c’è [MethodImpl] :

 [MethodImpl(MethodImplOptions.Synchronized)] public void SomeMethod() {/* code */} 

Questo può essere utilizzato anche su accessors (proprietà ed eventi):

 private int i; public int SomeProperty { [MethodImpl(MethodImplOptions.Synchronized)] get { return i; } [MethodImpl(MethodImplOptions.Synchronized)] set { i = value; } } 

Tieni presente che gli eventi di tipo campo sono sincronizzati per impostazione predefinita, mentre le proprietà di implementazione automatica non sono :

 public int SomeProperty {get;set;} // not synchronized public event EventHandler SomeEvent; // synchronized 

Personalmente, non mi piace l’implementazione di MethodImpl in quanto blocca this o typeof(Foo) – che è contro le migliori pratiche. L’opzione preferita è usare le tue serrature:

 private readonly object syncLock = new object(); public void SomeMethod() { lock(syncLock) { /* code */ } } 

Si noti che per gli eventi di tipo campo, l’implementazione del blocco dipende dal compilatore; nei vecchi compilatori Microsoft è un lock(this) / lock(Type) – tuttavia, nei compilatori più recenti utilizza gli aggiornamenti Interlocked – quindi thread-safe senza le brutte parti.

Ciò consente un utilizzo più granulare e consente l’utilizzo di Monitor.Wait / Monitor.Pulse ecc per comunicare tra thread.

Un post di blog correlato (successivamente rivisitato ).

 static object Lock = new object(); lock (Lock) { // do stuff } 

C # ha la sua versione della parola chiave “sincronizzata” java?

No. In C #, si lock esplicitamente lock risorse su cui si desidera lavorare in modo sincrono su thread asincroni. lock apre un blocco; non funziona a livello di metodo.

Tuttavia, il meccanismo sottostante è simile poiché il lock funziona richiamando Monitor.Enter (e successivamente Monitor.Exit ) sul runtime. Java funziona allo stesso modo, secondo la documentazione di Sun.

Prendi nota, con percorsi completi, della riga: [MethodImpl(MethodImplOptions.Synchronized)] dovrebbe assomigliare

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]

È ansible utilizzare invece l’istruzione di lock . Penso che questo possa solo sostituire la seconda versione. Inoltre, ricorda che sia la synchronized che il lock devono operare su un object.