2010-04-15 5 views
5

zurückkehren Ich mag mit aruguments das Verfahren in Thread nennen und einen Wert hier Beispielwie die Methode im Thread mit aruguments rufen und einen gewissen Wert

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

    } 

Ich weiß, das obige Beispiel erfolgreich ausgeführt werden zurückzukehren, aber wenn Methode fun1 wie das

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

dann wie kann ich das in thread aufrufen. Ist es möglich, .Any Körper Hilfe für me..i alle Möglichkeiten benötigen diese

+0

Ich denke, diese Beispiele sind genug. Wenn diese Antwort nicht Ihren Erwartungen entspricht, geben Sie das vollständige Szenario und was Sie benötigen. – Mohanavel

Antwort

6

Dies könnte ein anderer Ansatz sein. Hier wird die Eingabe als parametrisierter Thread übergeben und der Rückgabetyp wird im Delegate-Ereignis übergeben, so dass der Delegat bei Beendigung des Threads den Aufruf ausführt. Dies ist in Ordnung, um Ergebnisse zu erhalten, wenn der Thread fertig ist.

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

sollten Sie in der Lage sein, eine anonyme Methode oder Lambda verwendet volle statische Überprüfung zur Verfügung zu stellen:

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

oder wenn Sie wollen etwas mit dem Ergebnis tun:

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

aber beachten Sie, dass diese „etwas tun“ noch läuft im Rahmen des neuen Thread (aber mit Zugang zu den anderen Variablen in der äußeren Methode (Main) mit freundlicher Genehmigung von „erfassten Variablen ").

Wenn Sie C# 2.0 (und nicht oben), dann gilt:

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

und

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

danke, wenn andere Methoden verfügbar sind ... – ratty

+0

@ratty - was genau möchten Sie? –

0

können Sie die Überlastung ParameterizedThreadStart auf dem Thread-Konstruktor verwenden. Sie können ein Objekt als Parameter an Ihre Thread-Methode übergeben. Da es sich um einen einzelnen Objekt-Parameter handelt, erstelle ich normalerweise eine Parameter-Klasse für solche Threads. Dieses Objekt kann auch das Ergebnis der Thread-Ausführung speichern, das Sie lesen können, nachdem der Thread beendet wurde.

Vergessen Sie nicht, dass der Zugriff auf dieses Objekt während der Ausführung des Threads möglich ist, aber nicht "threadsicher" ist. Sie kennen das :)

Hier ein Beispiel:

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

Für einige Alternativen; currying:

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

oder Ihren eigenen Capture-Typen schreiben (dies ist im Großen und Ganzen vergleichbar zu dem, was der Compiler tut, für Sie, wenn Sie anon-Methoden/lambdas mit erfassten Variablen verwenden, aber unterschiedlich umgesetzt wurde):

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

Es ist viel einfachere Weise Funktion in separaten Thread ausführen:

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

Diese Funktion wird auf Thread-Pool-Thread ausgeführt werden, und die Logik ist völlig transparent für Ihre Anwendung. Im Allgemeinen schlage ich vor, solche kleinen Aufgaben im Thread-Pool statt dedizierten Thread auszuführen.

0

versuchen backgroundWorker können Sie Wert an das DoWork-Ereignis mit DoWorkEventArgs übergeben und Wert in RunWorkerCompleted recentive.

7

Ich mag Mark Gravell's Antwort. Sie können Ihr Ergebnis mit nur einer kleinen Änderung an den Hauptthread zurückgeben:

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