C # a-t-il sa propre version du mot-clé Java "synchronisé"?
C'est à dire. dans Java, vous pouvez spécifier une fonction, un objet ou un bloc de code, comme suit:
public synchronized void doImportantStuff() {
// dangerous code goes here.
}
ou
public void doImportantStuff() {
// trivial stuff
synchronized(someLock) {
// dangerous code goes here.
}
}
Premièrement - la plupart des classes n'auront jamais besoin d'être thread-safe. Utilisez YAGNI : appliquez la sécurité du fil uniquement lorsque vous savez que vous allez réellement l'utiliser (et le tester).
Pour les choses au niveau de la méthode, il y a [MethodImpl]
:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
Ceci peut également être utilisé sur des accesseurs (propriétés et événements):
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
Notez que les événements de type champ sont synchronisés par défaut, tandis que les propriétés implémentées automatiquement ne le sont pas :
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
Personnellement, je n'aime pas l'implémentation de MethodImpl
car elle verrouille this
ou typeof(Foo)
- ce qui va à l'encontre des meilleures pratiques. L'option préférée est d'utiliser vos propres verrous:
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
Notez que pour les événements de type champ, l'implémentation de verrouillage dépend du compilateur; dans les anciens compilateurs Microsoft, il s'agit d'une lock(this)
/lock(Type)
- cependant, dans les compilateurs plus récents, il utilise Interlocked
mises à jour - donc thread-safe sans les parties malveillantes.
Cela permet une utilisation plus granulaire et l'utilisation de Monitor.Wait
/Monitor.Pulse
etc. pour communiquer entre les threads.
A lié entrée de blog (plus tard revisité ).
static object Lock = new object();
lock (Lock)
{
// do stuff
}
C # a-t-il sa propre version du mot-clé Java "synchronisé"?
Non. En C #, vous explicitement lock
ressources sur lesquelles vous souhaitez travailler de manière synchrone sur des threads asynchrones. lock
ouvre un bloc; cela ne fonctionne pas au niveau de la méthode.
Cependant, le mécanisme sous-jacent est similaire car lock
fonctionne en appelant Monitor.Enter
(et ensuite _Monitor.Exit
_) lors de l'exécution. Java fonctionne de la même manière, selon le documentation de Sun .
Notez que, avec les chemins complets, la ligne: [MethodImpl(MethodImplOptions.Synchronized)]
devrait ressembler à
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
Vous pouvez utiliser l'instruction lock
à la place. Je pense que cela ne peut que remplacer la deuxième version. De plus, rappelez-vous que synchronized
et lock
doivent fonctionner sur un objet.