Instruction C# lock, quel objet à verrou?
J'ai 3 questions que j'ai besoin d'aide.
-
Quels sont les objets corrects/références à être passé sous la
lock
paramètres de déclaration? J'ai vu beaucoup d'exemples de codes et j'ai remarqué que les objets/références passé en pourrait éventuellement être non liées à la classe en cours ou de toute autre classe dans le programme tant que le modificateur d'accèsstatic
est non publique? E. g.:private Object anyObj = new Object(); lock(anyObj){.....} private static readonly object Locker = new object(); lock(Locker){.....}
Il n'a tout simplement pas de sens pour moi.
-
J'ai trouvé un exemple de code MSDN sur le multi threading qui utilise
lock
aussi des déclarations. Dans l'exemple il y a deuxtry
/catch
blocs avec leMonitor.Wait()
en son sein. Si je comprends la logique correctement, lereaderFlag
va interdire le programme pour entrer dans letry
/catch
bloc à tous.
Le code est l'exemple 2 à partir d'ici:
http://msdn.microsoft.com/en-us/library/aa645740(v=vs. 71).aspx -
Comment puis-je exécuter un thread qui s'exécute en arrière-plan tant que le Formulaire de Windows est actif?
Vous devez vous connecter pour publier un commentaire.
Comment et ce que vous verrouillage dépend de ce que vous faites.
Disons que vous travaillez avec un dispositif de type - dire une machine à café. Vous pourriez avoir une classe qui ressemble à ceci:
Dans ce cas, vous êtes à la protection de l'accès à la _coffeeHandle - un pointeur/poignée pour un appareil physique réel, donc c'est plutôt facile:
Donc, si je suis en cours d'exécution d'une application multithread, j' (probablement) ne veulent pas lire le nombre de tasses sont disponibles alors que je suis de distribution (c'est peut-être une erreur de matériel (hardware). En protégeant les accès à la poignée, je peux vous assurer qu'. Aussi, je ne peux pas être demandé de renoncer alors que je suis déjà de distribution - qui serait mauvais, de sorte que sa protégée. Finalement, je ne suis pas renoncer, sauf si j'ai assez de café disponibles et vous avez remarqué que je ne pas utiliser mon public de la propriété à vérifier que - de cette façon, l'action de s'assurer il y a assez de café et de distribution sont liées ensemble. Le mot magique est atomique - ils ne peuvent pas être coupés en dehors, sans créer de problèmes.
Vous utilisez un objet statique comme un verrou si vous en avez une et une seule instance d'une ressource qui doit protéger. Pensez, "puis-je avoir un singleton?" et qui servira de ligne directrice pour quand vous pourriez avoir besoin d'une statique de la serrure. Par exemple, disons que la Cafetière est un constructeur privé. Au lieu de cela, vous avez une méthode de fabrique que des constructions de machines à café:
Maintenant, dans ce cas, il se sent comme la Cafetière doit mettre en œuvre IDisposable de sorte que le manche est pris en charge, parce que si vous ne relâchez pas c'est que quelqu'un ne pourrait pas obtenir leur café.
Il y a quelques problèmes, bien - peut-être que si il n'y a pas assez de café, nous devrions en faire plus - et qui prend du temps. Diable - la distribution de café prend beaucoup de temps, c'est pourquoi nous faisons attention à la protection de nos ressources. Maintenant, vous pensez vraiment que tout cela bouilloire truc devrait être dans un thread qui lui est propre et qu'il devrait être un événement qui obtient déclenché lorsque le café est fait, et puis il commence à devenir compliqué et que vous comprenez l'importance de savoir ce que vous êtes le verrouillage de et quand, de sorte que vous n'avez pas la fabrication du bloc de café, parce que vous avez demandé combien de tasses sont là.
Et si les mots "d'impasse", "atomique", "surveiller", "attendre", et "pulse" tous les sons étrangers à vous, vous devriez envisager de faire des lectures sur le multitraitement/multithreading, en général, et de voir si vous pouvez résoudre la juste barbershop problème ou la salle à manger problème de philosophes, à la fois la quintessence des exemples de conflits de ressources.
IntPtr
est unstruct
. Comme un type de valeur, il obtient en boîte si vous l'utilisez aveclock
. Cela signifie que chaque appel àlock (_coffeeHandle)
obtient un autre objet de l'instance, ce qui signifie zéro synchronisation. Il est regrettable que cette réponse est (de loin) le plus de votes, car il est le moins utile/les plus nocifs de la grappe.1) votre code est incomplet. Vous verrouillez toujours autour d'un certain (partagé) de la ressource. Le
anyObject
doit avoir une correspondance 1-1 dans la vie avec cet objet partagé.Par exemple:
a) à la fois simple et la plus directe modèle:
il ya un inconvénient de ce modèle: que faire si un autre code bloque sur
sharedList
pour d'autres raisons? Généralement pas un problème pratique, mais c'est la raison pour laquelle le modèle recommandé est (b):Ou, lorsque l'objet partagé est statique (c) :
2) Les threads autre milieu
readerFlag
à true ou à false pour les blocs try/catch seront entrés. La synchronisation se fait avec le Moniteur.Pulse() et .Wait(). Notez que Wait() permet d'obtenir le verrou pour la durée de la s il est pas de l'impasse.lock
s utiliser le même objet.1: l'objet que vous utilisez définit /est défini par la serrure de la granularité vous tentez d'appliquer. Si c'est "rien d'appel à l'encontre de l'instance en cours", puis un
private readonly object syncLock = new object()
serait raisonnable. Si c'est "n'importe quel code, indépendamment de l'instance" (statique, en particulier), puisprivate readonly static object syncLock = new object()
. Parfois, il y a un évident "chose" que vous essayez de protéger qui servira également: une liste, une file d'attente, etc. Le principal mal les décisions sont:this
,typeof(...)
, toutstring
, tout type de valeur que vous êtes la boxe pour chaquelock
, et tout ce que vous avez une fuite à l'extérieur de l'instance.2:
Monitor.Wait
communiqués de les serrures de la thread en cours, en attente, soit une "impulsion" ou un délai d'attente, à quel point il se réveille et se joint à la file d'attente pour retrouver les verrous il avait (notez le "s" il est pour re-entrancy). Cela signifie que les deux threads peuvent utiliser unMonitor
à signal entre eux, par des impulsions et d'attente.3: sans rapport; mais, fondamentalement, "vérifier un indicateur périodiquement, et au moment d'être pulsé"
Selon la La documentation MSDN:
Dans mon cas, j'ai passé l'exacte objet statique que j'ai besoin de changer.