Bonjour à tous,
J'ai un petit souci pour appeler un thread avec des arguments.
Comment puis-je faire pour appeler ma fonction?Code:
1
2
3 Thread t1 = new Thread(new ThreadStart(fonction 1(arg1,arg2,arg3)); t1.Start();
Merci d'avance
Version imprimable
Bonjour à tous,
J'ai un petit souci pour appeler un thread avec des arguments.
Comment puis-je faire pour appeler ma fonction?Code:
1
2
3 Thread t1 = new Thread(new ThreadStart(fonction 1(arg1,arg2,arg3)); t1.Start();
Merci d'avance
e délégué ThreadStart ne permet pas de passer directement des paramètres à ton thread!
Lis ce cour et tu auras une bonne idée sur les threads:
cour_emerica_thread
Merci beaucoup, je vais lire cela tout de suite :)
Faudrait commencer par lire la documentation :aie:
Ça n'a pas de sens de connaitre des cours par cœur, faut avant tout apprendre à chercher une documentation.
On ne peut passer qu'un seul argument à un Thread, donc si tu veux passer tout plein d'info, bah tu créer un objet qui va pouvoir réunir toutes ces infos et tu passe cet objet, ou tu utilise des trucs comme une Hashtable, un Dictionary, etc..
+1000 !
Pour passer des arguments à un thread, il y a plusieurs approches possibles
- créer une classe qui représente la tâche à exécuter, avec les valeurs des paramètres et une méthode (par exemple "Run"), et utiliser cette méthode Run comme point d'entrée du thread :
C'est un peu la méthode "bulldozer", mais dans certains cas ça peut être pratiqueCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 class TaskWithParams { pubilc int Start { get; set; } public int End { get; set; } public void Run() { for(int i = Start; i <= End; i++) { ... } } } ... var task = new TaskWithParams { Start = 0, End = 42 }; new Thread(task.Run).Start();
- Autre approche un peu similaire : définir une classe qui contient les paramètres mais pas la méthode à exécuter, et utiliser la surcharge du constructeur de Thread qui prend en paramètre un ParameterizedThreadStart :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 class Params { pubilc int Start { get; set; } public int End { get; set; } } void Run(object o) { Params prm = (Params)o; for(int i = prm.Start; i <= prm.End; i++) { ... } } ... var prm = new Params { Start = 0, End = 42 }; new Thread(Run).Start(prm);
- Et l'approche la plus simple à mon avis : à partir de C# 2, on peut utiliser des méthodes anonymes :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 void Run(int start, int end) { for(int i = start; i <= end; i++) { ... } } // méthode anonyme "classique" (à partir de C#2) new Thread(delegate() { Run(0, 42); }).Start(); // expression lambda (à partir de C#3) new Thread(() => Run(0, 42)).Start();
Après recherche sur le forum je viens de tomber sur ce post.
J'ai quelques soucis pour comprendre le passage de parametres via un Thread.
Voilà comment je procède.
Et j'ai droit a une erreur :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 private void button2_Click(object sender, EventArgs e) { string var1 = "salut"; string var2 = "utilisateur"; Thread msg = new Thread(new ThreadStart(Mon_Message)); string[] variables = { var1, var2 }; msg.Start(variables); } private static void Mon_Message(string[] variables) { string var1 = variables[0]; string var2 = variables[1]; MessageBox.Show("Message : " + var1 + " " + var2); }
As-tu une idée d'ou ca peut venir ?Citation:
Erreur 1 Aucune surcharge pour 'Mon_Message' ne correspond au délégué 'System.Threading.ThreadStart'
Ma facon d'aborder la chose n'est pas correcte ?
Si j'ai bien compris le Thread ne peut accepter qu'un seul parametre, c'est pourquoi j'ai mis mes 2 variables dans un string[].
Merci d'avance :)
Le type de la variable est objet, pas string[]
En .Net "Object" est un "super objet", pas dans le sens où il est "super méga bien top cool", mais dans le sens où TOUS les autres types de données héritent de lui.
En conséquence, la valeur peut être tout et n'importe quoi, par contre, la signature de la méthode ne peut pas être changée, le paramètre est "Object" et rien d'autre. Il faut ensuite, dans le code de la méthode, caster le paramètre dans le type réellement passé.
EDIT : bon j'ai oublié la moitié
Il existe deux délégué pour démarrer un Thread, le premier est celui que tu utilise : ThreadStart.
Celui-ci n'accepte aucun paramètre. Voir la documentation.
Le second est ParameterizedThreadStart, qui lui accepte un paramètre. Voir la documentation.
Tu dois impérativement utiliser strictement le même prototype que celui du délégué, spécifié dans la documentation.
Avec une expression lambda ce serait plus simple...
Code:Thread msg = new Thread(() => Mon_Message(var1, var2));
@tomlev : Nickel ! Ca fonctionne impeccable. Je ne pensais pas que c'était possible de passer plusieurs parametres directement dans un Thread, du moins c'est ce que j'avais lu partout .... c'est pourtant ce qui est fait ici non ? Quel interet de se "compliquer" la vie avec un object si c'est faisable aussi facilement ?
@ctxnop : Merci pour les explications, et pour le fou rire devant l'ordi en lisant ton "super méga bien top cool".
@Nathanael : Merci à toi aussi pour l'idée.
Ben, non ce n'est pas possible; ici il n'en passe qu'un : la réference à l'objet.
Non, il n'en passe qu'un (bis).Citation:
c'est pourtant ce qui est fait ici non ?
C'est pourtant ce qu'il fait ici : il crée un objet. Je ne comprends pas ta remarque.Citation:
Quel interet de se "compliquer" la vie avec un object si c'est faisable aussi facilement ?
Je ne passe aucun paramètre au thread... J'indique seulement comme point d'entrée du thread une méthode anonyme sans paramètre qui appelle Mon_Message avec 2 paramètres. Nuance ;)
Les méthodes anonymes n'ont pas toujours existé en .NET. Elles existent depuis la version 2.0 (sous la forme delegate(paramètres) { corps de la méthode }). Les expressions lambda existent depuis C# 3 (.NET 3.5)
Non, je n'en passe aucun... enfin je passe le delegate au thread, mais le delegate ne prend aucun paramètre.
j'ai eu le même problème il y a quelque semaine je savais pas qu'on pouvait utiliser des expressions lambda
moi j'avais utilisé un tableau d'objet plus un invoke comme je faisait passé des composants winforms à l'intérieur.
je mettrais un petit exemple plus tard si vous voulez ;)