CrossThread operation encapsulé

Signaler
Messages postés
714
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
19 janvier 2017
-
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
-
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

Messages postés
794
Date d'inscription
vendredi 24 septembre 2004
Statut
Membre
Dernière intervention
19 août 2008
10
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
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
58
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-