2010-04-15 23 views
5

mi piace chiamare il metodo a filo con aruguments e restituire un certo valore qui esempiocome chiamare il metodo a filo con aruguments e restituire un valore

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); 
      } 
     } 

    } 

So che questo esempio precedente eseguito correttamente, ma se il metodo fun1 così

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

quindi come posso chiamarlo in thread. E 'possibile corpo .Any Aiuto per me..i bisogno di tutti i modi possibili questo

+0

Ritengo che questi esempi siano sufficienti. Se questa risposta non corrisponde alle vostre aspettative, date lo scenario completo e ciò di cui avete bisogno. – Mohanavel

risposta

6

Questo potrebbe essere un altro approccio. Qui l'input viene passato come parametro Thread e il tipo di ritorno viene passato nell'evento delegato, in modo tale che quando il thread completo chiamerà il delegato. Questo andrà bene per ottenere risultati al termine del thread.

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

Si dovrebbe essere in grado di utilizzare un metodo anonimo o lambda per fornire pieno controllo statico:

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

o se si desidera fare qualcosa con il risultato:

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

ma si noti che questo "fare qualcosa" corre ancora nel contesto del nuovo thread (ma con accesso alle altre variabili nel metodo esterno (Main) per gentile concessione di "variabili catturati ").

Se si dispone di C# 2.0 (e non sopra), quindi:

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

e

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

grazie se ci sono altri metodi disponibili ... – ratty

+0

@ ratty - cosa ti piacerebbe di preciso? –

0

È possibile utilizzare l'overload ParameterizedThreadStart sul costruttore Thread. Ti permette di passare un Oggetto come parametro al tuo metodo di discussione. Sarà un singolo parametro Object, quindi di solito creo una classe parametro per tali thread. Questo oggetto può anche memorizzare il risultato dell'esecuzione del thread, che è possibile leggere dopo che il thread è terminato.

Non dimenticare che l'accesso a questo oggetto mentre il thread è in esecuzione è possibile, ma non è "thread safe". Sapete il trapano :)

Ecco un esempio:

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

Per alcune alternative; accattivarsi:

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 lascia la tua cattura-tipo (questo è sostanzialmente paragonabile a quello che il compilatore fa per voi quando si utilizza anon-metodi/lambda con variabili catturati, ma è stata implementata in modo diverso):

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

C'è molto semplice metodo per eseguire la funzione in thread separato:

// 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); 

Questa funzione viene eseguita sul filo pool di thread, e che la logica è completamente trasparente per l'applicazione. In generale, suggerisco di eseguire piccole attività sul pool di thread anziché sul thread dedicato.

7

Mi piace la risposta di Mark Gravell. È possibile passare il risultato indietro al thread principale con una piccola modifica:

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);