2009-04-10 10 views
23

pasar dos parámetros para un nuevo hilo en el conjunto de subprocesos a veces puede ser complicado, pero parece que con las expresiones lambda y métodos anónimos, que puedo hacer esto:ThreadPool.QueueUserWorkItem con una expresión lambda y método anónimo

public class TestClass 
{ 
    public void DoWork(string s1, string s2) 
    { 
     Console.WriteLine(s1); 
     Console.WriteLine(s2); 
    } 
} 

try 
{ 
    TestClass test = new TestClass(); 
    string s1 = "Hello"; 
    string s2 = "World"; 
    ThreadPool.QueueUserWorkItem(
     o => test.DoWork(s1, s2) 
     ); 
} 
catch (Exception ex) 
{ 
    //exception logic 
} 

Ahora, ciertamente he simplificado este ejemplo, pero estos puntos son clave:

  • Los objetos de cadena que se transmiten son inmutables y por lo tanto para las hebras
  • El S1 y S2 se declaran las variables w dentro del alcance del bloque try, que salgo inmediatamente después de poner en cola el trabajo para el grupo de subprocesos, por lo que las variables s1 y s2 nunca se modifican después de eso.

¿Hay algún problema con esto?

La alternativa es crear una nueva clase que implemente un tipo inmutable con 3 miembros: prueba, s1 y s2. Eso parece un trabajo extra sin ningún beneficio en este punto.

+1

¿Por qué no escribes 'o => test.DoWork (s1, s2)' en lugar de la definición más detallada? –

+0

@Mehrdad: Porque soy muy nuevo en las expresiones lambda. ;) - ¡Gracias! –

+0

@Mehrdad: Lo cambié en la pregunta. –

Respuesta

16

No hay nada de malo en esto. El compilador básicamente está haciendo automáticamente lo que describió como su alternativa. Crea una clase para contener las variables capturadas (prueba, s1 y s2) y pasa una instancia de delegado a la lambda que se convierte en un método en la clase anónima. En otras palabras, si continúa con su alternativa, terminará con algo muy similar a lo que el compilador acaba de generar para usted.

2

Es una buena manera de hacerlo. No veo ninguna desventaja de usar lambdas. Es simple y limpio.

4

Para este ejemplo en particular, no, no hay nada de malo aquí. El estado que ha pasado al otro subproceso está completamente contenido y ninguno de los tipos implicados tiene ningún problema de afinidad de subprocesos.

+0

¿Qué pasa con el patrón general, entonces? ¿Cómo sabría si un tipo tiene problemas de afinidad de hilos? –

+0

Básicamente estás preguntando si una clase es segura o no. En mi implementación particular (en la mayoría de los casos) estoy usando objetos profundamente inmutables para que sean seguros para los hilos. Otras formas de hacer que los objetos sean enhebrables es usar el bloqueo, etc. –

+0

@Joel si un tipo tiene problemas de afinidad de hilos, está tostado. No puede hacer nada con eso en un hilo separado. Sin embargo, el patrón general es bueno (lo uso a menudo) – JaredPar

2

Lo que está viendo se refiere a un cierre. Como chuckj states, el compilador genera una clase en tiempo de compilación que corresponde a los miembros a los que se accede fuera del cierre.

Lo único de lo que tiene que preocuparse es si tiene parámetros de ref o out. Si bien las cadenas son inmutables, las referencias a ellas (o cualquier variable) NO lo son.

1

Un problema potencial con el patrón es que es muy tentador para expandirlo en algo más genérico, pero menos seguro como esto (código- cero no esperar que funcione):

public static void QueueTwoParameterWorkItem<T1, T2>(T1 value1, T2 value2, workDelegate<T1,T2> work) 
{ 
    try 
    { 
     T1 param1 = value1; 
     T2 param2 = value2; 
     ThreadPool.QueueUserWorkItem(
      (o) => 
      { 
       work(param1, param2); 
      }); 
    } 
    catch (Exception ex) 
    { 
     //exception logic 
    } 
} 
+0

En mi caso, tengo una clase base profundamente inmutable que podría usar para identificar T1 y T2 ... por lo que podría hacer que esto funcione en mi caso específico. Si no entiende los problemas de subprocesamiento, entonces usar el grupo de subprocesos queda descartado de todos modos. –

+0

De acuerdo: su caso específico está bien. Es cuando lo implementa como un patrón genérico hay preocupaciones. –

Cuestiones relacionadas