Je comprends qu'il s'agit d'un détail d'implémentation. Je suis en fait curieux de savoir ce que le détail de l'implémentation est dans Microsoft CLR. Maintenant, portez-moi car je n'ai pas étudié CS à l'université, donc j'ai peut-être manqué quelques principes fondamentaux. Mais ma compréhension de la "pile" et du "tas" telle qu'elle est implémentée dans le CLR tel qu'il est aujourd'hui est, je pense, solide. Je ne vais pas faire une déclaration parapluie inexacte comme "les types de valeur sont stockés sur la pile," par exemple. Mais, dans la plupart des scénarios courants - variables locales de vanille, de type valeur, passées en paramètres ou déclarées dans la méthode et non contenues dans une fermeture - les variables de type valeur sont stockées sur la pile (encore une fois, dans CLR de Microsoft).Où sont stockés les paramètres de type valeur de référence pour les appels de méthode asynchrones dans CLR de Microsoft?
Je suppose que ce que je ne suis pas sûr de est où ref
valeur des paramètres de type sont disponibles dans
origine ce que je pensais était que, si la pile d'appel ressemble à ceci (à gauche = bas).
A() -> B() -> C()
... alors une variable locale déclarée dans le cadre de a et passé en paramètre ref
à B pourrait encore être stockés sur la pile - il ne pouvions pas? B aurait simplement besoin de l'emplacement de la mémoire où cette variable locale a été stockée A cadre (pardonnez-moi si ce n'est pas la bonne terminologie, je pense que ce que je veux dire, de toute façon).
Je réalise cela ne pouvait être strictement vrai, cependant, quand il me est apparu que je pouvais faire:
delegate void RefAction<T>(ref T arg);
void A()
{
int x = 100;
RefAction<int> b = B;
// This is a non-blocking call; A will return immediately
// after this.
b.BeginInvoke(ref x, C, null);
}
void B(ref int arg)
{
// Putting a sleep here to ensure that A has exited by the time
// the next line gets executed.
Thread.Sleep(1000);
// Where is arg stored right now? The "x" variable
// from the "A" method should be out of scope... but its value
// must somehow be known here for this code to make any sense.
arg += 1;
}
void C(IAsyncResult result)
{
var asyncResult = (AsyncResult)result;
var action = (RefAction<int>)asyncResult.AsyncDelegate;
int output = 0;
// This variable originally came from A... but then
// A returned, it got updated by B, and now it's still here.
action.EndInvoke(ref output, result);
// ...and this prints "101" as expected (?).
Console.WriteLine(output);
}
Ainsi, dans l'exemple ci-dessus, où est x
(dans A « s portée) stocké? Et comment ça marche? Est-ce que c'est en boîte? Si non, est-il sujet à la collecte des ordures maintenant, en dépit d'être un type de valeur? Ou la mémoire peut-elle être immédiatement récupérée?
Je m'excuse pour la question longue. Mais même si la réponse est assez simple, peut-être que cela sera instructif pour les autres qui se retrouvent à se demander la même chose à l'avenir.
http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx – Brian