Pour être honnête, je suis un peu boiteux quand il s'agit de filetage;) Donc, je demande un peu d'aide.Synchroniser le sous-fil avec le fil principal - problème pas si évident
Supposons que nous ayons une sorte de contrôle sur lequel nous pouvons dessiner des graphiques. Il existe également une méthode qui dessine un graphique sur ce contrôle. Le problème est que la méthode de cartographie a accès uniquement à l'un des champs du contrôle et nous avons besoin d'actualiser le contrôle lorsque le graphique est prêt.
Alors supposons que notre contrôle ressemble à ça:
class ChartingControl : System.Windows.Forms.Control
{
public Canvas canvas;
public void Refresh();
/*
... other fields/methods
*/
}
où Canvas
est une classe utilisée pour dessiner l'image (quelque chose comme Graphics).
La méthode de cartographie a accès uniquement à l'objet canvas
(nous ne pouvons pas changer), il ressemble à ça:
public static void DrawChart(canvas)
{ /* draw */ }
Cette méthode peut être appelée à partir d'un thread séparé, travailleur de fond, etc ... Et je besoin de synchroniser avec le thread principal et appelez Refresh()
lorsque le graphique est prêt.
En ce moment, lorsque le graphique est prêt, je mis un drapeau sur l'objet de toile
public static void DrawChart(canvas)
{ /* draw */
canvas.Tag = true; // chart is ready
}
et j'ai un travailleur de fond courir à l'intérieur du contrôle de cartographie et d'écoute si le champ canvas.Tag
a changé et si oui, il appelle Refresh()
Mais il semble que ma méthode est un peu rude, facile à échouer etc ... Yat-il une meilleure méthode pour l'améliorer?
Limitations:
- nous ne pouvons pas modifier la classe Canvas
. La seule chose que nous pouvons utiliser est le champ Tag
(de type object
- nous pouvons modifier la méthode de classe et le dessin ChartingControl
-. Il peut y avoir de nombreux contrôles de représentation graphique
-. Nous ne contrôlons pas la façon dont DrawChart
est appelé Il peut être appelé dans un thread séparé, ou non. il est appelé ailleurs. Tout ce que nous pouvons faire est de créer le contrôle et la méthode DrawChart et essayer de les comunicate en quelque sorte
Solution
OK, je l'ai résolu de cette façon : dans ChartingControl
J'ai créé un ManualResetEvent manualReset
et un travailleur de fond.
travailleur Bacground attend le manualReset
:
void backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
manualReset.WaitOne(); // Wait for a chart to be ready
}
et à la fin appelle la méthode Reset()
void backgroundWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
Refresh();
}
Je passe l'objet manualReset
à l'intérieur canvas.Tag
et à l'intérieur méthode de dessin, lorsque le graphique est prêt j'appelle manualReset.Set();
pour passer le signal que le graphique est prêt.
La méthode DrawChart démarre un nouveau thread ou vous l'appelez dans un autre thread? –
Je l'appelle dans un autre fil – Gacek