2009-05-08 21 views
10

¿Cuál es la diferencia entre los dos códigos siguientes? ¿Habrá algún problema usando el segundo?Enhebrado y expresiones lambda

Escenario 1:

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

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

Escenario 2

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

En el escenario 2, no estoy pasando la excepción como un parametro a la ThreadPool. ¿Cómo se produce la distribución de subprocesos del objeto de excepción? ¿Habrá algún problema? ¿Cuáles son las limitaciones de hacer esto si es que hay alguno? La gran ventaja es que puede pasar cualquier número de parámetros muy fácilmente.

Respuesta

14

La única diferencia es que en el escenario dos está cerrando la variable e que mueve efectivamente la variable de pila e a un tipo personalizado que se mueve al montón para que no lo pierda.

Creo que esto debería funcionar bien.

Edit: En cuanto al rendimiento, no debería haber una diferencia significativa entre los dos escenarios. En el escenario 1 ya está pasando la excepción como state al método QueueUserWorkItem que mueve internamente esa referencia de excepción al montón. La única sobrecarga es que cuando usa un cierre es que el compilador crea un tipo para usted y almacena las variables capturadas como campos de ese tipo.

+0

¿Existen implicaciones de rendimiento? –

+0

Buena respuesta. De hecho, la expresión lambda genera un cierre (http://en.wikipedia.org/wiki/Closure_(computer_science)) para que la variable (puede ser más de uno en el caso general) se pueda referenciar en otro lugar. – Noldorin

+0

@anon: No, no debería haber implicaciones de rendimiento hasta donde yo sé. – Noldorin

1

para notar, en lugar de la Lambda, se podría hacer lo mismo con un método anónimo, y también funcionaría en C# 2.0:

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

+1 Lo que ha publicado es exactamente lo que el compilador genera para la declaración lambda en la pregunta del OP. –

+0

Sí, pero si el OP hubiera incluido más parámetros, ¿hubiera funcionado el método anónimo? –