Invalidieren einer Objektreferenz, während ein anderer Thread eine Methode auf die er ausführt (NET)
-
18-09-2019 - |
Frage
(Ich bin interessiert an der .NET CLR)
Was genau passiert, wenn ein Thread das Objekt ein Variablenreferenz ändert, während ein anderer Thread eine Methode auf dem ursprünglichen Objekt ausgeführt wird?
Zum Beispiel, sagen die Art Foo
eine Variable ‚Bar‘ hat vom Typ Bar
und Bar
hat keinen Klasse-Level-Zustand (bis jetzt zumindest, ich möchte dieses Szenario einfach halten):
// Thread 1
foo.Bar = new Bar();
foo.Bar.SomeMethod();
In der Zwischenzeit, bevor diese beendet Ausführung ...
// Thread 2
foo.Bar = new Bar();
Was geschieht mit der Methode, die (ist?) Ausgeführt wird auf Thread 1? Ist alles, was es bereits auf dem Stapel vervollständigen muss?
Gibt es Dinge ändern, wenn Thread 2 tut dies statt?
foo.Bar = null;
Lösung
Wenn der Anruf bereits garantiert innerhalb SomeMethod()
sein, dann nichts Ungewöhnliches passiert, - this
ist ein implizites Argument für Methoden, so wäre es nie den Wert des Feldes (oder Eigenschaft, je nachdem, was es ist) direkt
Ob Sie wirklich, dass garantieren kann, ist eine andere Sache.
Andere Tipps
- edit: korrigiert verwirrenden Satz
Nun, die Zuordnung tatsächlich auf die Variable atomar sein wird, so ist es nicht den Anruf mögen plötzlich erkennen, ‚oh mein ich null bin!‘ während der Ausführung .SomeMethod ()
Was können passieren, ist aber, dass foo.Bar.SomeMethod () selbst wird nicht genannt werden, da Thread 2 wird (vielleicht) gesetzt haben es zuerst auf null; so wird es einfach nicht ausführen (es wird mit einem Null-ref Ausnahme abstürzen).
Das gleiche gilt mit dem ersten Beispiel; es wird nur .SomeMethod auf dem neuen Objekt aufrufen.
Ich glaube, Sie denken, die Dinge ändern können, während .SomeMethod läuft, nicht wahr? Nein. Nichts wird dort ändern. Es wird nach wie vor den Kontext selbst hat.
Was genau passiert, wenn ein Thread das Objekt ein Variablenreferenz ändert, während ein anderer Thread eine Methode auf dem ursprünglichen Objekt ausgeführt wird?
Was passiert, ist, dass Sie Ihren Code neu schreiben, um richtig Zugriff auf diese Felder zu synchronisieren.