// Si 1 thread appelle directement cette fonction, ça ne marchera pas
public void ModifFormulaire(string sNewMsg)
{
maListBox.Items.Add(sNewMsg);
}
// Par contre, celui ci marchera :
public delegate void AddListItem(String sNewMsg);
public AddListItem myDelegate;
public void ModifFormulaire(string sNewMsg)
{
if( maListBox.InvokeRequired )
{
myDelegate = new AddListItem(ModifFormulaire);
this.Invoke(myDelegate , new Object[] {sNewMsg});
}
else
{
// sur le thread du formulaire
maListBox.Items.Add(sNewMsg);
}
}
public partial class Form1 : Form
{
public delegate void parStr(string s);
private parStr _delParStr;
private Thread _thread; // on doit pouvoir manager le thread (jamais local)
/// <summary>
/// .Ctor
/// </summary>
public Form1()
{
InitializeComponent();
// Une seule instance du delegate suffit
_delParStr = new parStr(addList);
}
/// <summary>
/// Form1_Load
/// </summary>
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = "Form loaded...";
}
/// <summary>
/// start thread
/// </summary>
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "Start thread...";
if (_thread == null)
{
(_thread = new Thread(new ThreadStart(threadFunc))).Start();
label1.Text = "threadState : " + _thread.ThreadState.ToString();
}
}
/// <summary>
/// threadFunc
/// </summary>
private void threadFunc()
{
try
{
int i = 0;
while (true)
{
addList("Ligne Liste " + (i++).ToString());
// ici le gif continue de bien tourner !
// et l'utilisateur à accès à l'UI
}
}
catch (ThreadAbortException)
{
_thread.Join(5000);
_thread = null;
Thread.ResetAbort();
}
addList("End threadFunc ...");
}
/// <summary>
/// Cancel thread
/// </summary>
private void button2_Click(object sender, EventArgs e)
{
if (_thread != null )
{
Cursor.Current = Cursors.WaitCursor;
label1.Text = "Cancelling thread...";
try
{
_thread.Abort();
label1.Text = "thread aborded...";
}
finally
{
_thread.Join(5000);
_thread = null;
label1.Text += " - thread null...";
Cursor.Current = Cursors.Default;
}
}
}
/// <summary>
/// addList
/// </summary>
private void addList(string s)
{
if (listBox1.InvokeRequired)
{
this.Invoke(_delParStr, s);
}
else
{
listBox1.Items.Insert(0, s);
// Si le thread fini par lui même, sans "Abord"
if (s.StartsWith("End threadFunc") && _thread != null)
{
_thread.Join(5000);
_thread = null;
label1.Text += " - ok thread null...";
}
}
}
/// <summary>
/// Form1_FormClosing
/// </summary>
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
button2.PerformClick();
}
}
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Modifié par nagashima le 5/11/2013 à 07:53
Oui je connais le concept, mon problème est que le flux d'information est trop important => ce qui fait que, vu que j'ajoute de nombreuses données à ma liste box de manière très rapide, l'interface graphique ramme (elle ne freeze pas, elle galère).
Ce que je cherche serai plutot de divisier ma forme graphique de manière à ce que ma liste soit gérée depuis un thread (par exemple, la Form est gérée dans un thread, si on ouvre une Form soeur c'est un nouveau thread => basiquement c'est ce que je veux faire).
mais merci essayer de m'aider ;)
naga
PS : pour ma part, je déclare de cette manière :
histoire de ne pas avoir à faire d'invoke dans les appels.
5 nov. 2013 à 13:00
as tu essayé tout simplement de mettre un Application.DoEvents() après
chaque modif de la liste ?
5 nov. 2013 à 13:39
Le problème ne vient pas de là, le doEvent me permettrai dans le cas d'un jeux d'instruction de redonner la mains, mais dans mon cas c'est déjà le cas.
En fait, le problème est que j'appel mon action avec un interval de temps inférieur au temps qu'il faut pour la fonction "snitch" pour ajouter un élément à la liste ...
fait ce code, avec une Form qui contient une liste et une image (en prenant soins d'ajouter un gif aux ressources) :
les ajouts dans la liste se font bien. Maintenant, commentes et tu remarque que la forme est freezée => on ajoute à la liste tellement souvent que ca prend totalement le focus.
Donc l'idée serai que l'élément de list dans ma forme soit un thread graphique à part entière, comme si on ouvrait une fenêtre soeur