CrossThread operation encapsulé

scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017 - 30 sept. 2007 à 19:21
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 - 1 oct. 2007 à 16:35
le sujet des opérations cross thread à partir de .NET 2.0 a fait fumer beaucoup de clavier

Histoire de ne pas réinventer la route car on trouve toujours le même exemple de code pour définir un texte dans un contrôle, voici un bout de code qui permet aussi de changer la couleur et de vider un texte.

La question est :
Dois-je continuer à étendre ces quelques fonctions d'interface ou bien une lib ou quelque chose plus pratique existe déjà ?

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Text;

namespace MyNameSpace
{
    public sealed class CrossThreadControlUtility
    {
        // These delegates enables asynchronous calls for setting the text, color, font... property on a control.
        delegate void SetForeColorCallback(Control output, Color foreColor);
        delegate void SetTextCallback(TextBoxBase output, string text, bool appendCarriageReturn);
        delegate void ClearTextBoxCallback(TextBoxBase output);

        public static void SetForeColor(Control output, Color foreColor)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (output.InvokeRequired)
            {
                SetForeColorCallback d = new SetForeColorCallback(SetForeColor);
                //this.Invoke(d, new object[] { output, foreColor});
                output.Parent.Invoke(d, new object[] { output, foreColor });
            }
            else
            {
                output.ForeColor = foreColor;
            }
        }

        public static void WriteToOutput(TextBoxBase output, string text, bool appendCarriageReturn)
        {
            if (output.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(WriteToOutput);
                output.Parent.Invoke(d, new object[] { output, text, appendCarriageReturn });
            }
            else
            {
                output.AppendText(text);
                if (appendCarriageReturn)
                {
                    output.AppendText("\n");
                }
                output.SelectionStart = output.TextLength;
                output.ScrollToCaret();
            }
        }

        public static void ClearTextBox(TextBoxBase output)
        {
            if (output.InvokeRequired)
            {
                ClearTextBoxCallback d = new ClearTextBoxCallback(ClearTextBox);
                output.Parent.Invoke(d, new object[] { output });
            }
            else
            {
                output.Clear();
            }
        }

        private CrossThreadControlUtility() { }
        ~CrossThreadControlUtility() { }
    }
}

2 réponses

Nikoui Messages postés 794 Date d'inscription vendredi 24 septembre 2004 Statut Membre Dernière intervention 19 août 2008 13
30 sept. 2007 à 19:33
Etant donné que cette exception est succeptible de se produire sur tous les contrôles du framework, et sur toutes les propriétés de chacun des contrôles, ce genre de code va vite devenir une usine a gaz... Pour ma part, je préfère appliquer là où c'est necessaire le petite bout de code "rustine" (avec le test sur InvokeRequired et l'appel au Invoke).

Idéalement, en implémentant le design pattern MVC on arrive a restreindre les classes qui accèdent directement aux IHM, et on peut même essayer de s'arranger pour que cela se fasse toujours avec le bon thread (même si ce n'est pas toujours aussi évident).

<hr size="2" width="100%" />
Working as designed
www.nikoui.fr
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
1 oct. 2007 à 16:35
Je me permets de rajouter ce link qui sera très certainement fort utile à des gens qui tomberont sur ce topic et qui ont des problèmes avec le cross threading: http://www.csharpfr.com/tutorial.aspx?id=174

<hr />
-My Blog-
0
Rejoignez-nous