2009-05-08 15 views
10

Qual è la differenza tra i due pezzi di codice qui sotto? Ci saranno problemi nell'usare il secondo?Threading e espressioni lambda

Scenario 1:

private void Log(Exception e) 
{ 
    ThreadPool.QueueUserWorkItem(new WaitCallback(Log), e); 
} 

private void Log(object obj) 
{ 
    Exception e = (Exception)obj; 
    Logger.Log(e); 
} 

Scenario 2

private void Log(Exception e) 
{ 
    ThreadPool.QueueUserWorkItem(
     (obj) => 
      { 
       Logger.Log(e); 
      }); 
} 

Nello scenario 2, io non sto passando l'eccezione in un Parametro al ThreadPool. Come si verifica il thread marshalling dell'oggetto di eccezione? Ci saranno problemi? Quali sono i limiti di fare questo se del caso? Il grande vantaggio è che puoi passare facilmente qualsiasi numero di parametri.

risposta

14

L'unica differenza è che nello scenario due si sta chiudendo la variabile e che sposta effettivamente la variabile di stack e in un tipo personalizzato che viene spostato nell'heap in modo da non perderlo.

Penso che questo dovrebbe funzionare bene.

Modifica: Per quanto riguarda le prestazioni, non ci dovrebbe essere una differenza significativa tra i due scenari. Nello scenario 1 si passa già l'eccezione come state al metodo QueueUserWorkItem che sposta internamente tale riferimento di eccezione sull'heap. L'unico overhead è che quando si utilizza una chiusura è che il compilatore crea un tipo per te e memorizza le variabili acquisite come campi su quel tipo.

+0

Ci sono delle implicazioni sulle prestazioni? –

+0

Buona risposta. In effetti, l'espressione lambda genera una chiusura (http://en.wikipedia.org/wiki/Closure_(computer_science)) in modo che la variabile (che può essere più di una nel caso generale) possa essere referenziata altrove. – Noldorin

+0

@anon: No, non ci dovrebbero essere implicazioni di prestazioni per quanto ne so. – Noldorin

1

Solo per notare, invece della Lambda, si potrebbe fare lo stesso con un metodo anonimo, e sarebbe anche lavorare in C# 2.0:

ThreadPool.QueueUserWorkItem(delegate(Object e) 
    { 
     Logger.Log(e as Exception); 
    }); 
+0

+1 Quello che hai postato è esattamente ciò che il compilatore genera per l'istruzione lambda nella domanda dell'OP. –

+0

Sì, ma se l'OP includeva più parametri, il metodo anonimo avrebbe funzionato? –

Problemi correlati