2010-12-01 11 views
4

Ich habe eine C# 2.0-Anwendung mit einem Formular, das eine Klasse verwendet, die einen Thread enthält.Invoke/BeginInvoke aus einem Thread aufrufen

In der Thread-Funktion, anstatt den Event-Handler direkt aufzurufen, wird es aufgerufen. Dies hat zur Folge, dass das besitzende Formular InvokeRequired/BeginInvoke nicht aufrufen muss, um seine Steuerelemente zu aktualisieren.

public class Foo 
{ 
    private Control owner_; 
    Thread thread_; 

    public event EventHandler<EventArgs> FooEvent; 

    public Foo(Control owner) 
    { 
     owner_ = owner; 
     thread_ = new Thread(FooThread); 
     thread_.Start(); 
    } 

    private void FooThread() 
    { 
     Thread.Sleep(1000); 
     for (;;) 
     { 
      // Invoke performed in the thread 
      owner_.Invoke((EventHandler<EventArgs>)InternalFooEvent, 
       new object[] { this, new EventArgs() }); 
      Thread.Sleep(10); 
     } 
    } 

    private void InternalFooEvent(object sender, EventArgs e) 
    { 
     EventHandler<EventArgs> evt = FooEvent; 
     if (evt != null) 
      evt(sender, e); 
    } 
} 

public partial class Form1 : Form 
{ 
    private Foo foo_; 

    public Form1() 
    { 
     InitializeComponent(); 

     foo_ = new Foo(this); 
     foo_.FooEvent += OnFooEvent; 
    } 

    private void OnFooEvent(object sender, EventArgs e) 
    { 
     // does not need to call InvokeRequired/BeginInvoke() 
     label_.Text = "hello"; 
    } 
} 

Dies ist offensichtlich im Gegensatz zu dem von Microsoft APIs verwendet, die Hintergrund-Threads wie System.Timers.Timer und System.IO.Ports.SerialPort verwenden. Gibt es irgendetwas an sich falsch mit dieser Methode? Ist es in irgendeiner Weise gefährlich?

Danke, PaulH


Edit: auch, was passiert, wenn die Form der Veranstaltung abonnieren nicht sofort? Würde es die Nachrichtenwarteschlange des Formulars mit Ereignissen verstopfen, an denen das Formular nicht interessiert war?

+0

siehe bitte editieren – Falcon

Antwort

3

Dies ist ein Threadsafe-Aufruf, die Methode wird im Thread des Formulars verarbeitet.

Nichts ist falsch, wenn man es aus einer konzeptuellen Perspektive betrachtet.

Timer sind für solche Aufgaben jedoch eleganter. Es könnte jedoch sein, dass ein Timer mit einem Intervall von 10ms die GUI verlangsamt, weshalb Invoke wahrscheinlich verwendet wurde.

Sie benötigen keinen Aufruf von InvokeRequired, da es klar ist, dass das Steuerelement in einem anderen Thread ist. Außerdem muss BeginInvoke nur aufgerufen werden, wenn Sie eine Methode asynchron aufrufen möchten, was hier offensichtlich nicht der Fall ist.

In Bezug auf Ihre Bearbeitung: Nein, die Nachrichtenwarteschlange wird nicht verstopft. Kein Ereignis wird ausgelöst, wenn kein Handler registriert wurde. Schau dir deinen Code noch mal an;)

Verwandte Themen