2010-03-22 12 views

Respuesta

41

Suponga que tiene un método:

void A(string a, int b) {} 

Esto debería funcionar (.NET 2.0):

ThreadStart starter = delegate { A("word", 10); }; 
Thread thread = new Thread(starter); 

thread.Start(); 

y los siguientes (más corto) para versiones superiores:

ThreadStart starter =() => A("word", 10); 
Thread thread = new Thread(starter); 

//or just... 
//Thread thread = new Thread(() => A("word",10)); 

thread.start() 
+0

'nuevo Thread (() => A ("palabra", 10))' para C# 3 +. – Dykam

+0

Exactamente. Estaba pensando en .NET 2.0. –

+0

@Dykam, ¿puedes explicar el significado de "() =>" en el ejemplo dado por ti (nuevo Tema (() => A ("palabra", 10))) – Techee

4

Las soluciones tsocks dadas pueden no ser buenas para todos iones porque especifica los parámetros en el momento de la creación del delegado ThreadStart, en lugar de en el momento de la ejecución. Esto podría generar errores porque los parámetros pueden cambiar antes de la ejecución, que probablemente no sea la que usted desea. Supongamos que necesita para crear varios hilos en un bucle, cada uno con su propio parámetros:

void CreateAndRunThreads() 
{ 
    List<ThreadStart> threadStartsList = new List<ThreadStart>(); 

    //delegate creation 
    for (int i = 0; i < 5; i++) 
    { 
     ThreadStart ts = delegate() { PrintInteger(i); }; 
     threadStartsList.Add(ts); 
    } 

    //delegate execution (at this moment i=5 in the previous loop) 
    foreach(ThreadStart ts in threadStartsList) 
    { 
     Thread t = new Thread(ts); 
     t.Start(); 
    } 
} 
private void PrintInteger(int i) 
{ 
    Debug.WriteLine("The integer value: "+i); 
} 

La salida aquí es la siguiente:

The integer value: 5 
The thread 0x17f0 has exited with code 0 (0x0). 
The integer value: 5 
The integer value: 5 
The thread 0x10f4 has exited with code 0 (0x0). 
The integer value: 5 
The thread 0x1488 has exited with code 0 (0x0). 
The integer value: 5 
The thread 0x684 has exited with code 0 (0x0). 

en cuenta que todos los delegados imprimen el valor 5, no del 0 al 4. Esto se debe a que los delegados de ThreadStart usan la variable "i", tal como está en el momento de la ejecución, no en el momento de la creación del delegado. De modo que cualquier cambio (i ++ en el ciclo) al parámetro posterior al momento de la creación del delegado se reflejará en el valor del parámetro a medida que el delegado se ejecuta.

Una solución a este problema es utilizar ParameterizedThreadStart y una clase personalizada que agrega todos sus parámetros (si hay más). Con parameterizedThreadStart, pasa los parámetros en el momento de la ejecución. Esto sería algo como esto:

class CustomParameters 
{ 
    public int IntValue { get; set; } 
    public string FriendlyMessage { get; set; } 
} 

private void CreateAndRunThreadsWithParams() 
{ 
    List<ParameterizedThreadStart> threadStartsList = new List<ParameterizedThreadStart>(); 

    //delegate creation 
    for (int i = 0; i < 5; i++) 
    { 
     ParameterizedThreadStart ts = delegate(object o) { PrintCustomParams((CustomParameters)o); }; 
     threadStartsList.Add(ts); 
    } 

    //delegate execution 
    for (int i=0;i<threadStartsList.Count;i++) 
    { 
     Thread t = new Thread(threadStartsList[i]); 
     t.Start(new CustomParameters() { IntValue = i, FriendlyMessage = "Hello friend! Your integer value is:{0}"}); 
    } 
} 

private void PrintCustomParams(CustomParameters customParameters) 
{ 
    Debug.WriteLine(string.Format(customParameters.FriendlyMessage, customParameters.IntValue)); 
} 

Se muestra la salida de aquí:

Hello friend! Your integer value is:1 
The thread 0x1510 has exited with code 0 (0x0). 
Hello friend! Your integer value is:0 
The thread 0x13f4 has exited with code 0 (0x0). 
Hello friend! Your integer value is:2 
The thread 0x157c has exited with code 0 (0x0). 
Hello friend! Your integer value is:3 
The thread 0x14e4 has exited with code 0 (0x0). 
Hello friend! Your integer value is:4 
The thread 0x1738 has exited with code 0 (0x0). 

(El orden de ejecución no es determinista, es una carrera entre los hilos)

4

para C# 3.0 puede evitar la matriz de objetos feos que pasa con métodos anónimos:

void Run() 
{ 
    string param1 = "hello"; 
    int param2 = 42; 

    Thread thread = new Thread(delegate() 
    { 
     MyMethod(param1,param2); 
    }); 
    thread.Start(); 
} 

void MyMethod(string p,int i) 
{ 

} 
0

una de las formas más simples t parámetro pase o para enhebrar como

Thread xmlThread =new Thread(()=>WriteLog(LogTypes.Message, "Flag", "Module", "Location", "Text", "Stacktrace")); 
       xmlThread.Start(); 



private object WriteLog(LogTypes logTypes, string p, string p_2, string p_3, string p_4, string p_5) 
     { 

     } 
0
public void Start() 
     { 
      var t1 = new Thread((message) => { Console.WriteLine(message); }); 
      //the parametirized threadstart accepts objects, it is not generic 
      var t2 = new Thread(number => { var num = (int)number; 
      Console.WriteLine(num++); 
      }); 
      var t3 = new Thread((vals)=> work(vals)); 

      t1.Start(); 
      t2.Start(); 
      t3.Start(20); 
     } 

     public void work(params object[] vals) 
     { 

     } 
Cuestiones relacionadas