2010-03-22 7 views

Antwort

41

Angenommen, Sie haben eine Methode:

void A(string a, int b) {} 

Dies sollte (.NET 2.0) arbeiten:

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

thread.Start(); 

und die folgenden (kürzere) für höhere Versionen:

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

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

thread.start() 
+0

'new Thread (() => A ("Wort", 10))' für C# 3 + einzufädeln. – Dykam

+0

Genau. Ich dachte an .NET 2.0. –

+0

@Dykam, können Sie die Bedeutung von "() =>" in dem von Ihnen angegebenen Beispiel erläutern (neuer Thread ((=) => A ("Wort", 10))) – Techee

4

Die Lösungen tsocks hat gegeben, möglicherweise nicht gut für alle situat Ionen, weil es die Parameter zum Zeitpunkt der Erstellung des ThreadStart-Delegaten angibt, statt zum Zeitpunkt der Ausführung. Dies könnte zu Fehlern führen, da sich die Parameter vor der Ausführung ändern könnten, was wahrscheinlich nicht das ist, was Sie wollen. Angenommen, Sie müssen mehrere Threads in einer Schleife erstellen, die jeweils mit einer eigenen Parameter:

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

Der Ausgang ist hier wie folgt:

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

Beachten Sie, dass alle Teilnehmer den Wert 5 gedruckt, nicht 0 durch 4. Dies liegt daran, dass die ThreadStart-Delegierten die Variable "i" verwenden, wie sie zum Zeitpunkt der Ausführung vorliegt, und nicht zum Zeitpunkt der Erstellung des Delegaten. Jede Änderung (i ++ in der Schleife) an den Parameter nach dem Zeitpunkt der Erstellung des Delegaten spiegelt sich im Wert des Parameters wider, wenn der Delegat ausgeführt wird.

Eine Lösung für dieses Problem ist die Verwendung von ParameterizedThreadStart und einer benutzerdefinierten Klasse, die alle Ihre Parameter aggregiert (wenn es mehr gibt). Mit parameterizedThreadStart übergeben Sie die Parameter zum Zeitpunkt der Ausführung. Dies würde in etwa so aussehen:

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

Der Ausgang hier gezeigt wird:

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

(Die Reihenfolge der Ausführung nicht deterministisch ist, es ist ein Rennen zwischen den Fäden)

4

für C# 3.0 Sie können vermeiden, dass das hässliche Objekt-Array mit anonymen Methoden übergibt:

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

einer der einfachsten Weg t o Pass Parameter als

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

     } 
Verwandte Themen