2010-04-15 7 views
5

me gusta llamar el método de hilo con aruguments y devolver algún valor en este ejemplocómo llamar el método de hilo con aruguments y devolver algún valor

class Program 
    { 
     static void Main() 
     { 
      Thread FirstThread = new Thread(new ThreadStart(Fun1)); 
      Thread SecondThread = new Thread(new ThreadStart(Fun2)); 
      FirstThread.Start(); 
      SecondThread.Start();   


     } 
     public static void Fun1() 
     { 
      for (int i = 1; i <= 1000; i++) 
      { 
       Console.WriteLine("Fun1 writes:{0}", i); 
      } 
     } 
     public static void Fun2() 
     { 
      for (int i = 1000; i >= 6; i--) 
      { 
       Console.WriteLine("Fun2 writes:{0}", i); 
      } 
     } 

    } 

Sé que este ejemplo anterior se ejecutan correctamente pero si fun1 método como este

public int fun1(int i,int j) 
{ 
    int k; 
    k=i+j; 
    return k; 
} 

entonces cómo puedo llamar esto en el hilo. ¿Es posible ayudar al cuerpo .Any para me..i necesitan todas las formas posibles de este

+0

Creo que estos ejemplos son suficientes. Si esta respuesta no coincide con sus expectativas, brinde el escenario completo y lo que necesita. – Mohanavel

Respuesta

6

Este puede ser otro enfoque. Aquí la entrada se pasa como un subproceso parametrizado y se pasa el tipo de devolución en el evento de delegado, de modo que cuando se completa el subproceso se llame al delegado. Esto estará bien para obtener un resultado cuando se completa el hilo.

public class ThreadObject 
    { 
     public int i; 
     public int j; 
     public int result; 
     public string Name; 
    } 



    public delegate void ResultDelegate(ThreadObject threadObject); 

    public partial class Form1 : Form 
    { 

     public event ResultDelegate resultDelete; 

     public Form1() 
     { 
      InitializeComponent(); 

      resultDelete += new ResultDelegate(resultValue); 
     } 

     void resultValue(ThreadObject threadObject) 
     { 
      MessageBox.Show("Thread Name : " + threadObject.Name + " Thread Value : " + threadObject.result); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      ThreadObject firstThreadObject = new ThreadObject(); 
      firstThreadObject.i = 0; 
      firstThreadObject.j = 100; 
      firstThreadObject.Name = "First Thread"; 

      Thread firstThread = new Thread(Fun); 
      firstThread.Start(firstThreadObject); 


      ThreadObject secondThreadObject = new ThreadObject(); 
      secondThreadObject.i = 0; 
      secondThreadObject.j = 200; 
      secondThreadObject.Name = "Second Thread"; 

      Thread secondThread = new Thread(Fun); 
      secondThread.Start(secondThreadObject); 

     } 


     private void Fun(object parameter) 
     { 
      ThreadObject threadObject = parameter as ThreadObject; 

      for (; threadObject.i < threadObject.j; threadObject.i++) 
      { 
       threadObject.result += threadObject.i; 

       Thread.Sleep(10); 
      } 

      resultValue(threadObject); 
     } 
    } 
24

Usted debe ser capaz de utilizar un método anónimo o lambda para proporcionar un chequeo total estática:

Thread FirstThread = new Thread(() => Fun1(5, 12)); 

o si desea hacer algo con el resultado:

Thread FirstThread = new Thread(() => { 
    int i = Fun1(5, 12); 
    // do something with i 
}); 

pero tenga en cuenta que este "hacer algo" todavía funciona en el contexto del nuevo hilo (pero con acceso a las otras variables en el método exterior (Main) cortesía de "variables capturadas ").

Si tiene C# 2.0 (y no antes), entonces:

Thread FirstThread = new Thread((ThreadStart)delegate { Fun1(5, 12); }); 

y

Thread FirstThread = new Thread((ThreadStart)delegate { 
    int i = Fun1(5, 12); 
    // do something with i 
}); 
+0

gracias si hay otros métodos disponibles ... – ratty

+0

@ratty - ¿qué le gustaría exactamente? –

0

Usted puede utilizar la sobrecarga de ParameterizedThreadStart en el constructor de rosca. Le permite pasar un Objeto como parámetro a su método de hilo. Va a ser un único parámetro de objeto, por lo que generalmente creo una clase de parámetro para tales subprocesos. Este objeto también puede almacenar el resultado de la ejecución del subproceso, que puede leer una vez que el subproceso ha finalizado.

No olvide que es posible acceder a este objeto mientras el hilo está en ejecución, pero no es "seguro para subprocesos". Lo de siempre :)

He aquí un ejemplo:

void Main() 
{ 
    var thread = new Thread(Fun); 
    var obj = new ThreadObject 
    { 
     i = 1, 
     j = 15, 
    }; 

    thread.Start(obj); 
    thread.Join(); 
    Console.WriteLine(obj.result); 
} 

public static void Fun(Object obj) 
{ 
    var threadObj = obj as ThreadObject; 
    threadObj.result = threadObj.i + threadObj.j; 
} 

public class ThreadObject 
{ 
    public int i; 
    public int j; 
    public int result; 
} 
0

Para algunas alternativas; currificación:

static ThreadStart CurryForFun(int i, int j) 
{ // also needs a target object if Fun1 not static 
    return() => Fun1(i, j); 
} 

Thread FirstThread = new Thread(CurryForFun(5, 12)); 

o escribir su propio tipo de captura (esto es ampliamente comparable a lo que hace el compilador para que cuando se utiliza anon-methods/lambdas con variables capturadas, pero se ha implementado de manera diferente):

class MyCaptureClass 
{ 
    private readonly int i, j; 
    int? result; 
    // only available after execution 
    public int Result { get { return result.Value; } } 
    public MyCaptureClass(int i, int j) 
    { 
     this.i = i; 
     this.j = j; 
    } 
    public void Invoke() 
    { // will also need a target object if Fun1 isn't static 
     result = Fun1(i, j); 
    } 
} 
... 
MyCaptureClass capture = new MyCaptureClass(5, 12); 
Thread FirstThread = new Thread(capture.Invoke); 
// then in the future, access capture.Result 
1

Hay mucho más simple manera de ejecutar la función de hilo separado:

// Create function delegate (it can be any delegate) 
var FunFunc = new Func<int, int, int>(fun1); 
// Start executing function on thread pool with parameters 
IAsyncResult FunFuncResult = FunFunc.BeginInvoke(1, 5, null, null); 
// Do some stuff 
// Wait for asynchronous call completion and get result 
int Result = FunFunc.EndInvoke(FunFuncResult); 

Esta función se ejecutará el subproceso del grupo de hilo, y que la lógica es completamente transparente para su aplicación. En general, sugiero ejecutar tareas tan pequeñas en el grupo de subprocesos en lugar de en el subproceso dedicado.

7

Me gusta la respuesta de Mark Gravell. Puede pasar su resultado nuevamente al hilo principal con solo una pequeña modificación:

int fun1, fun2; 
Thread FirstThread = new Thread(() => { 
    fun1 = Fun1(5, 12); 
}); 
Thread SecondThread = new Thread(() => { 
    fun2 = Fun2(2, 3); 
}); 

FirstThread.Start(); 
SecondThread.Start(); 
FirstThread.Join(); 
SecondThread.Join(); 

Console.WriteLine("Fun1 returned {0}, Fun2 returned {1}", fun1, fun2); 
Cuestiones relacionadas