2010-05-11 31 views
5

Quiero pasar una función que toma un parámetro al Constructor ThreadStart en C#. Sin embargo, parece que esto no es posible, ya que me sale un error de sintaxis que trato de hacer algo como estopasando parámetros a un hilo

Thread t1 = new Thread(new ThreadStart(func1(obj1)); 

donde obj1 es un objeto de tipo List<string> (por ejemplo).

Si quiero que un hilo ejecute esta función que toma un objeto como parámetro, y planeo crear 2 de estos hilos simultáneamente con diferentes valores de parámetros, ¿cuál es el mejor método para lograr esto?

+1

¿Qué versión de .NET estás usando? –

+0

¡Guau! Lo hice antes creando una clase para contener los datos que utilizará el hilo, ¡pero no tenía idea de que hubiera tantas formas diferentes de desollar a este animal! –

Respuesta

7

Necesita ParametrizedThreadStart para pasar un parámetro a un hilo.

Thread t1 = new Thread(new ParametrizedThreadStart(func1); 
t1.Start(obj1); 
+0

Muchas gracias ... este método funciona ...sin embargo, la definición de func1 en este caso tendrá que ser void func1 (estado del objeto) y no puede ser void func1 (Lista obj1) ¿por qué es este el caso? – assassin

+0

Así es como se define el tipo de delegado 'ParametrizedThreadStart'. Tendrás que devolver el 'objeto' a' List 'dentro de' func1'. – Thomas

13

Si está utilizando .NET 3.5 o superior, una opción es utilizar un lambda para esto:

var myThread = new System.Threading.Thread(() => func1(obj1)); 
+0

Muchas gracias! – assassin

3

Prueba esto:

var bar = 0.0; 
Thread t = new Thread(() => 
    { 
     Foo(bar); 
    }); 
t.IsBackground = true; 
t.Start(); 

o en su caso:

Object obj1 = new Object(); 
Thread t = new Thread(() => 
    { 
     func1(obj1); 
    }); 
t.IsBackground = true; 
t.Start(); 
7

Puede comenzar un nuevo hilo como este:

Thread thread = new Thread(delegate() { 
    // Code here. 
}); 
thread.Start(); 

Dentro del anonymous method tiene acceso a las variables que estaban en el alcance cuando se creó el delegado.

3

Editar asesino tenía problemas para conseguir este código para trabajar, por lo que he incluido una aplicación completa consola de ejemplo al final de este post.

 


{ // some code 
    Thread t1 = new Thread(MyThreadStart); 
    t1.Start(theList); 
} 

void MyThreadStart(object state) 
{ 
    List<string> theList = (List<string>)state; 
    //.. 
} 

 

Esta es mi edición: A continuación se muestra una aplicación completa de la consola - la técnica realmente funciona:

 

using System; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      System.Threading.Thread t = new System.Threading.Thread(MyThreadStart); 
      t.Start("Hello"); 
      System.Console.ReadLine(); 
     } 


     static void MyThreadStart(object state) 
     { 
      System.Console.WriteLine((string)state); 
     } 
    } 
} 

 
+0

Esto no funciona ... lo intenté ... el método ParametrizedThreadStart sugerido por Thomas funciona. – assassin

+0

@assassin Te lo aseguro, funciona. He editado mi entrada para incluir una aplicación de consola que puede pegar directamente en Visual Studio y ejecutar. Esta sintaxis ha funcionado desde .Net 2.0, y si reemplaza el "nuevo Thread (MyThreadStart)" con "new Thread (nuevo delegado) – JMarsch

3

Es este el efecto que está buscando?

 static void Main(string[] args) 
    { 
     var list = new List<string>(){ 
      "a","b","c" 
     }; 

     Thread t1 = new Thread(new ParameterizedThreadStart(DoWork)); 

     t1.Start(list); 

     Console.ReadLine(); 

    } 

    public static void DoWork(object stuff) 
    { 
     foreach (var item in stuff as List<string>) 
     { 
      Console.WriteLine(item); 
     } 
    } 
1
static void func1(object parameter) 
{ 
    // Do stuff here. 
} 

static void Main(string[] args) 
{ 
    List<string> obj1 = new List<string>(); 
    Thread t1 = new Thread(func1); 
    t1.Start(obj1); 
} 

Se trata de utilizar un nuevo delegado en .Net 2.0 ParameterizedThreadStart llamada. Puedes leer al respecto here.

0

¿Es absolutamente necesario utilizar un objeto Thread? ¿O solo está buscando que se realice el procesamiento multiproceso? Un enfoque más "moderna" sería utilizar un delegado asincrónica como tal:

private delegate void FuncDelegate(object obj1); 
. 
. 
. 
FuncDelegate func = func1; 
IAsyncResult result = func.BeginInvoke(obj1, Completed, func); 

// do other stuff 
. 
. 
. 

private void Completed(IAsyncResult result) 
{ 
    ((FuncDelegate)result.AsyncState).EndInvoke(result); 

    // do other cleanup 
} 

Un método aún más "moderna" sería utilizar Tasks en .NET 4 TPL.

Cuestiones relacionadas