2010-03-22 5 views

Répondre

41

Supposons que vous ayez une méthode:

void A(string a, int b) {} 

Cela devrait fonctionner (.NET 2.0):

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

thread.Start(); 

Et les éléments suivants (plus court) pour les versions supérieures:

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

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

thread.start() 
+0

'nouveau fil (() => A ("mot", 10))' pour 3 + C#. – Dykam

+0

Exactement. Je pensais à .NET 2.0. –

+0

@Dykam, pouvez-vous élaborer la signification de "() =>" dans l'exemple donné par vous (new Thread (() => A ("word", 10))) – Techee

4

Les solutions tsocks a donné pourrait ne pas être bon pour tout situat ions car il spécifie les paramètres au moment de la création du délégué ThreadStart, au lieu de au moment de l'exécution. Cela pourrait conduire à des erreurs car les paramètres peuvent changer avant l'exécution ce qui n'est probablement pas ce que vous voulez. Supposons que vous devez créer plusieurs threads dans une boucle, chacun avec ses propres paramètres:

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

La sortie est ici comme suit:

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

Notez que tous les délégués imprimés la valeur 5, non 0 à 4. En effet, les délégués ThreadStart utilisent la variable "i", telle qu'elle est au moment de l'exécution, et non au moment de la création du délégué. Donc tout changement (i ++ dans la boucle) au paramètre après le moment de la création du délégué sera reflété dans la valeur du paramètre lorsque le délégué s'exécute.

Une solution à ce problème consiste à utiliser ParameterThreadStart et une classe personnalisée qui agrège tous vos paramètres (s'il y en a plus). Avec parameterizedThreadStart, vous passez les paramètres au moment de l'exécution. Cela ressemblerait à quelque chose comme ceci:

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

La sortie est montrée ici:

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

(L'ordre d'exécution n'est pas déterministe, il est une course entre les fils)

4

pour C# 3.0 vous pouvez éviter le tableau d'objets laide en passant par des méthodes anonymes:

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

l'un des moyens les plus simples t o paramètre passe à fil selon

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

     } 
Questions connexes