Bonjour,

Je me suis fait un objet (TemporayString) qui gère une chaine de caractères qui s'efface automatiquement au bout d'un temps défini (à l'aide d'un Timer).
J'ai donc :
- une méthode AddChar(char value) qui me permet d'ajouter un caractère à la chaîne temporaire. Cette méthode déclenche l'évènement CharAdded.
- un évènement TemporaryStringReset qui est déclenché lorque le Timer est écoulé.

Dans ma form qui utilise une instance de l'objet, je m'abonne aux évènements CharAdded et TemporaryStringReset pour mettre à jour un label.
- Lorsque j'appelle la méthode Addchar, l'évènement CharAdded est déclenché et mon label est bien mis à jour.
- Mais lorsque le Timer est écoulé, l'évènement TemporaryStringReset est déclenché mais il est réceptionné par la form dans un thread séparé !
Je dois donc faire un invoke de mon label pour pouvoir le mettre à jour.

Sauriez-vous d'où cela peut provenir ? Est-ce normal ? Puis-je modifier la conception de l'objet pour récupérer l'évènement dans le même thread ?

Code de la classe TemporaryString :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/// <summary>
/// A temporary string
/// </summary>
public class TemporaryString
{
    #region Fields
    // Default interval :
    private const double _DEFAULTINTERVAL = 1000;
    // Timer instance :
    private Timer _Timer;
    // String value :
    private string _Value;
 
    public event EventHandler TemporaryStringReset;
 
    public event EventHandler CharAdded;
 
    /// <summary>
    /// String value
    /// </summary>
    public string Value
    {
        get { return _Value; }
    }
    #endregion
 
    #region Constructors
    /// <summary>
    /// Initializes a new instance of TemporaryString, using the default interval, which is 1 second
    /// </summary>
    public TemporaryString()
        : this(_DEFAULTINTERVAL)
    { }
 
    /// <summary>
    /// Initializes a new instance of TemporaryString, using the given interval
    /// </summary>
    /// <param name="interval">Time period</param>
    public TemporaryString(double interval)
    {
        this._Timer = new Timer(interval);
        this._Value = string.Empty;
        this._Timer.Elapsed += new ElapsedEventHandler(this._Timer_Elapsed);
        this._Timer.Enabled = true;
        this._Timer.AutoReset = false;
    }
    #endregion
 
    #region Methods
    /// <summary>
    /// Adds a char to the string value
    /// </summary>
    /// <param name="value">Char to add to the string value</param>
    public void AddChar(char value)
    {
        this._Value += value.ToString();
        // Reset the timer :
        this._Timer.Stop();
        this._Timer.Start();
 
        // Fire CharAdded event :
        EventHandler handler = CharAdded;
        // NOTE : Make a temporary copy of the event to avoid possibility of a race condition 
        // if the last subscriber unsubscribes immediately after the null check and before the event is raised.
        if (handler != null)
            handler(this, new EventArgs());
    }
 
    /// <summary>
    /// Elapsed timer event
    /// </summary>
    /// <param name="sender">Source object</param>
    /// <param name="e">Elapsed event arguments</param>
    private void _Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        this._Value = string.Empty;
        // Stop the timer :
        this._Timer.Stop();
 
        // Fire the TemporaryStringReset event :
        EventHandler handler = TemporaryStringReset;
        // NOTE : Make a temporary copy of the event to avoid possibility of a race condition 
        // if the last subscriber unsubscribes immediately after the null check and before the event is raised.
        if (handler != null)
            handler(this, new EventArgs());
    }
    #endregion
}
Utilisation de l'objet dans la form :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public partial class Form1 : Form
{
    TemporaryString ts;
    delegate void SetTextCallback(string text);
 
    public Form1()
    {
        InitializeComponent();
 
        ts = new TemporaryString(2000);
        ts.TemporaryStringReset += new EventHandler(ts_TemporaryStringReset);
        ts.CharAdded += new EventHandler(ts_CharAdded);
    }
 
    private void SetText(string text)
    {
        if (label1.InvokeRequired)
        {
            label1.Invoke(new SetTextCallback(SetText), new object[] { text });
        }
        else
        {
            if (string.IsNullOrEmpty(text))
            {
                label1.Text = string.Empty;
            }
            else
            {
                label1.Text = text;
            }
        }
    }
 
    void ts_CharAdded(object sender, EventArgs e)
    {
        SetText(ts.Value);
    }
 
    void ts_TemporaryStringReset(object sender, EventArgs e)
    {
        SetText("vide");
    }
 
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        ts.AddChar(Convert.ToChar(e.KeyValue));
    }
}
Merci de votre aide