Disons que vous avez une opération simple qui s'exécute sur un fil d'arrière-plan. Vous voulez fournir un moyen d'annuler cette opération, vous créez donc un drapeau booléen que vous mettez à true à partir du gestionnaire d'événement de clic d'un bouton d'annulation.
private bool _cancelled;
private void CancelButton_Click(Object sender ClickEventArgs e)
{
_cancelled = true;
}
Maintenant, vous définissez le drapeau d'annulation à partir du fil de l'interface graphique, mais vous le lisez à partir du fil d'arrière-plan. Devez-vous verrouiller avant d'accéder au bool ?
Auriez-vous besoin de faire cela (et évidemment de verrouiller aussi le gestionnaire d'événement du clic du bouton) :
while(operationNotComplete)
{
// Do complex operation
lock(_lockObject)
{
if(_cancelled)
{
break;
}
}
}
Ou est-il acceptable de faire cela (sans verrou) :
while(!_cancelled & operationNotComplete)
{
// Do complex operation
}
Ou pourquoi ne pas marquer la variable _cancelled comme volatile. Est-ce nécessaire ?
[Je sais qu'il existe la classe BackgroundWorker avec sa méthode intégrée CancelAsync(), mais ce qui m'intéresse ici, c'est la sémantique et l'utilisation du verrouillage et de l'accès threadé aux variables, pas l'implémentation spécifique, le code est juste un exemple].
Il semble y avoir deux théories.
1) Parce qu'il s'agit d'un simple type intégré (et l'accès aux types intégrés est atomique en .net) et parce que nous n'écrivons qu'à un seul endroit et ne lisons que sur le fil d'arrière-plan, il n'est pas nécessaire de verrouiller ou de marquer comme volatile.
2) Vous devez le marquer comme volatile car si vous ne le faites pas, le compilateur peut optimiser la lecture dans la boucle while parce qu'il pense que rien n'est capable de modifier la valeur.
Quelle est la technique correcte ? (Et pourquoi ?)
[Il semble y avoir deux écoles de pensée clairement définies et opposées sur ce sujet. Je cherche une réponse définitive sur ce sujet, alors s'il vous plaît, si possible, postez vos raisons et citez vos sources avec votre réponse].