Evénements, multi-threading & simplicité
Bonjour à tous !
Je suis en train de développer un objet qui permet de créer un serveur TCP multi-clients.
Cette object contient quelques thread ainsi que des evenements (OnNewConnection, OnNewMessage…).
Pour illustrer mon problème, imaginons un objet nommé classServer qui lance un thread au moment de son instanciation. Ce thread fait appel à la méthode ThreadListen qui attend la connexion d’un nouveau client sur un port donné. Lorsqu’un nouveau client se connecte, l’événement OnNewClient est déclenché.
Voici donc un code très simplifié mais fonctionnel de cet objet :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
class classServer
{
public delegate void NewClientEventHandler(object sender, EventArgs e);
public event NewClientEventHandler OnNewClient;
Thread MyThread;
public classServer()
{
MyThread = new Thread(ThreadListen);
MyThread.Start();
}
private void ThreadListen()
{
while(true)
{
Thread.Sleep(1000); //attente dune nouvelle connexion
if (OnNewClient != null)
OnNewClient(this, new EventArgs());
}
}
} |
Si nous désirons utiliser cet objet tel quel et afficher la phrase « nouveau client » dans une textbox lorsque l’événement OnNewClient a lieu, voici le code que nous allons devoir mettre en place :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
public partial class Form1 : Form
{
classServer MyServer;
private delegate void AjoutTextBox1Text(string p_text);
private void AjoutTextBox1(string p_text)
{
textBox1.Text = p_text;
}
public Form1()
{
InitializeComponent();
MyServer = new classServer();
MyServer.OnNewClient += new classServer.NewClientEventHandler(MyServer_OnNewClient);
}
void MyServer_OnNewClient(object sender, EventArgs e)
{
AjoutTextBox1Text AjoutText = new AjoutTextBox1Text(AjoutTextBox1);
Invoke(AjoutText, new object[] { (object)"Nouveau client" });
}
} |
Je trouve ce code vraiment lourd est je préfèrerais largement qu’il ressemble à quelque chose comme ceci :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public partial class Form1 : Form
{
classServer MyServer;
public Form1()
{
InitializeComponent();
MyServer = new classServer();
MyServer.OnNewClient += new classServer.NewClientEventHandler(MyServer_OnNewClient);
}
void MyServer_OnNewClient(object sender, EventArgs e)
{
textBox1.Text = "Nouveau client";
}
} |
Evidement, ce code est impossible. Au moment de mettre à jour notre textbox, le CLR va gentiment nous préciser que nous désirons réaliser une opération entre 2 thread, que ce n’est pas bien et qu’il refuse de faire une telle chose.
Pourtant, j’aimerais beaucoup que mon objet soit utilisable de cette manière. Y’aurait-il un moyen de modifier mon objet classServer de manière à le rendre plus simple d’utilisation?
Si vous avez LA solution ou ne serait-ce qu'une piste, je suis preneur !
Merci
utiliser un textbox dans un thread
mon code est constitué de 2thread qui doivent utiliser des textbox, et jutilise la meme procédure que kizab i.e à peu prés ça:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public partial class Form1 : Form
{
classServer MyServer;
private delegate void AjoutTextBox1Text(string p_text);
private void AjoutTextBox1(string p_text)
{
textBox1.Text = p_text;
}
public Form1()
{
InitializeComponent();
MyServer = new classServer();
MyServer.OnNewClient += new classServer.NewClientEventHandler(MyServer_OnNewClient);
}
void MyServer_OnNewClient(object sender, EventArgs e)
{
AjoutTextBox1Text AjoutText = new AjoutTextBox1Text(AjoutTextBox1);
Invoke(AjoutText, new object[] { (object)"Nouveau client" });
}
} |
j'ai aussi essayé de comprendre comment utiliser le AsyncOperationManager mais j'ai pas bien saisi le principe de leur utilisation,et en quoi ça peut m'aider pour ne pas avoir l'exception généré par le Invoke?
merci