309 votes

Version C# du mot-clé synchronisé de Java ?

Le C# possède-t-il sa propre version du mot-clé "synchronisé" de Java ?

En Java, il peut être spécifié soit à une fonction, un objet ou un bloc de code, comme ceci :

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

o

public void doImportantStuff() {
   // trivial stuff

   synchronized {
      // dangerous code goes here.
   }
}

458voto

Marc Gravell Points 482669

Premièrement, la plupart des classes n'auront jamais besoin d'être thread-safe. Utilisez YAGNI La sécurité des fils : n'appliquez la sécurité des fils que lorsque vous savez que vous allez réellement l'utiliser (et la tester).

Pour le niveau méthode, il y a [MethodImpl] :

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

Cela peut également être utilisé sur les 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ées par défaut, tandis que les propriétés auto-implémentées ne sont pas :

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

Personnellement, je n'aime pas la mise en œuvre de l'option MethodImpl comme il se verrouille this o typeof(Foo) - ce qui est contraire aux meilleures pratiques. La meilleure option est d'utiliser vos propres serrures :

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

Notez que pour les événements de type champ, l'implémentation du 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 les mises à jour, qui sont donc sûres pour les fils de discussion, mais sans les parties désagréables.

Ceci permet une utilisation plus granulaire, et permet l'utilisation de Monitor.Wait / Monitor.Pulse etc. pour communiquer entre les threads.

Un rapport entrée de blog (plus tard revisité ).

55voto

Jan Gressmann Points 2758
static object Lock = new object();

lock (Lock) 
{
// do stuff
}

39voto

Konrad Rudolph Points 231505

Le C# possède-t-il sa propre version du mot-clé "synchronisé" de Java ?

Non. En C#, vous devez explicitement lock les ressources sur lesquelles vous voulez travailler de manière synchrone à travers des threads asynchrones. lock ouvre un bloc ; ça ne fonctionne pas au niveau de la méthode.

Cependant, le mécanisme sous-jacent est similaire puisque lock fonctionne en invoquant Monitor.Enter (et par la suite Monitor.Exit ) sur le runtime. Java fonctionne de la même manière, selon le Documentation sur le soleil .

7voto

Traubenfuchs Points 181

Prenez note, avec des chemins complets en ligne : [MethodImpl(MethodImplOptions.Synchronized)] devrait ressembler à

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

5voto

James Points 1732

Vous pouvez utiliser le lock à la place. Je pense que cela ne peut que remplacer la deuxième version. De plus, n'oubliez pas que les deux synchronized y lock besoin d'opérer sur un objet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X