2013-04-21 11 views
8

Si consideri il seguente metodo:Devo arrestare il cronometro se il metodo di inclusione sta per ritornare?

DoTimeIntensiveOperation() 
{ 
    var t = new Stopwatch(); 

    foreach(var element in a_very_long_array) 
    { 
     DoATimeConsumingTask(element); 
    } 

    Console.WriteLine("Took me " + t.Elapsed); 
    return; 
} 

Devo chiamare t.Stop() prima di tornare?

Per quanto ne so, il garbage collector distruggerà tutto ciò che non ha una catena di riferimento che ritorna al metodo principale. L'unico riferimento allo Stopwatch creato è t, quindi quando DoTimeIntensiveOperation, t verrà liberato e lo Stopwatch dovrebbe essere idoneo per la distruzione. Ma il fatto che sia ancora "ticchettante" interferisce con il GC?

risposta

8

No, ho lanciato questo test rapido e sembra che una volta eseguito il GC, il cronometro venga distrutto. (Sentitevi liberi di correggere il codice)

static void Main(string[] args) 
{ 
     DoTimeIntensiveOperation(); 

     GC.Collect(); 
     while (swRef.IsAlive) 
     { 
     } 
     Console.WriteLine("Destroyed"); 
} 

static WeakReference swRef = null; 
static void DoTimeIntensiveOperation() 
{ 
    Stopwatch sw = new Stopwatch(); 
    sw.Start(); 
    swRef = new WeakReference(sw); 
    return; 
} 

L'uscita è Destroyed quando GC.Collect si chiama. Certamente, in un programma reale è improbabile che chiami esplicitamente GC.Collect ma questo è per mostrare che l'oggetto Cronometro viene distrutto una volta fuori dall'ambito del metodo anche se non è stato chiamato Stop.