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é ).