Invalidando un riferimento oggetto mentre un altro thread sta eseguendo un metodo su di esso (NET)
-
18-09-2019 - |
Domanda
(Mi interessa il CLR .NET)
Cosa accade esattamente quando un thread modifica l'oggetto una variabile fa riferimento mentre un altro thread sta eseguendo un metodo sull'oggetto originale?
Ad esempio, dire che il tipo di Foo
ha una variabile 'Bar' del tipo Bar
, e Bar
non ha uno stato a livello di classe (per ora almeno, mi piacerebbe mantenere questo scenario semplice):
// Thread 1
foo.Bar = new Bar();
foo.Bar.SomeMethod();
Nel frattempo, prima che questo termina l'esecuzione ...
// Thread 2
foo.Bar = new Bar();
Cosa succede al metodo che è (era?) In esecuzione su Thread 1? È tutto ciò che deve portare a termine già in pila?
Lo fa cambiare le cose, se il thread 2 fa questo, invece?
foo.Bar = null;
Soluzione
Se la chiamata è garantito per essere già dentro SomeMethod()
, quindi nulla di insolito che accadrà - this
è un argomento implicito per i metodi, quindi sarebbe non usare mai il valore del campo (o proprietà, qualunque essa sia) direttamente
Sia che si può veramente garantire questa è un'altra questione.
Altri suggerimenti
- edit: corretto frase confusa
Beh, in realtà l'assegnazione alla variabile sarà atomico, quindi non è come la chiamata sarà improvvisamente conto 'oh mio io sono nulla!' durante l'esecuzione .SomeMethod ()
Cosa possono accadere, però, è che foo.Bar.SomeMethod () in sé non sarà chiamato, perché Thread 2 avrà (forse) impostato a NULL prima; quindi semplicemente non eseguirà (che andrà in crash con un'eccezione rif null).
Lo stesso vale con il primo esempio; sarà solo chiamare .SomeMethod sul nuovo oggetto.
Credo che stai pensando le cose possono cambiare mentre .SomeMethod è in esecuzione, giusto? No. Niente cambierà in là. Sarà ancora il contesto di se stessa.
Cosa accade esattamente quando un thread modifica l'oggetto una variabile fa riferimento mentre un altro thread sta eseguendo un metodo sull'oggetto originale?
Quello che succede è che si riscrivere il codice per sincronizzare correttamente l'accesso a questi campi.