C# [WPF] "BeginInvoke(Delegate, Object[])" und Delegate.BeginInvoke([Parameterliste, ...

  • Ersteller Ersteller Tersus
  • Erstellt am Erstellt am
T

Tersus

Gast
[WF] "BeginInvoke(Delegate, Object[])" und Delegate.BeginInvoke([Parameterliste, ...

Zum Thema "Thread" habe ich eigentlich schon allehand gelesen und verstanden, wenn auch nicht alles.

In einer WF kann ich auf die Methode BeginInvoke(Delegate, Object[]) zugreifen, die mir den übergebenen Delegaten in einem neuen Thread ausführt.

Nun ist es möglich, von einem Delegaten die Funktion public IAsyncResult BeginInvoke([Parameterliste ,] AsyncCallback, Object) aufzurufen!

Beispiel:

Code:
    public partial class Form1 : Form
    {

        public delegate void Delegator(string text);
        //      public delegate void AsyncCallback(IAsyncResult ar);

        Delegator del;
        Test test;

        public Form1()
        {

            InitializeComponent();

            test = new Test(textBoxL);

        }

        private void button_Click(object sender, EventArgs e)
        {
            del = (string text) => test.ausgabe(text);

            BeginInvoke(del, "Erste Zeichenkette!");

            del.BeginInvoke("Zweite Zeichenkette!", new AsyncCallback(_AsyncCallback), null);

        }

        private void _AsyncCallback(IAsyncResult ergebnis)
        {

        }

    }

Interessant sind nur Zeile 23 und Zeile 25!

Die Implementierung in Zeile 23 führt zur gewünschten Ausgabe.

Aber was passiert genau in Zeile 25?

Vielen Dank schon mal im Voraus!
 
Zuletzt bearbeitet von einem Moderator:
Zunächst mal: Dein Code ist Windows Forms und nicht WPF. Glücklicherweise ist das hier aber nicht entscheidend.

Beide Methoden haben ein stark unterschiedliche Bedeutung:
Das erste "BeginInvoke" (Zeile 23) führt den übergebenen Delegate auf dem GUI-Thread aus. Das ist nötig wenn man aus einem anderen Thread auf Controls zugreifen will, weil das eben nur aus dem GUI-Thread heraus möglich ist.
Das zweite "BeginInvoke" (Zeile 25) ist einfach eine Methode einen Delegate asynchron auszuführen. Im Prinzip genau das Gegenteil der ersten Variante, weil der Code eben nicht auf dem GUI-Thread ausgeführt wird.
 
Ist es dann überhaupt möglich, eine GUI Komponente, wie eine Instanz der Klasse TextBox, in einer Methode einer Instanz, die nicht als Form deklariert ist, in einem neuen Thread zu verändern?

Beispiel:

Code:
namespace ThreadTests
{
    public delegate void Delegator(string text);

    public partial class Form1 : Form
    {
        Test test;

        public Form1()
        {
            InitializeComponent();

            test = new Test(textBox);
        }

        private void button_Click(object sender, EventArgs e)
        {
            test.async("test");
        }
    }

    public class Test
    {
        TextBox tb;
        Delegator del;

        public Test(TextBox tb)
        {
            this.tb = tb;
        }

        public void async(string text)
        {
            del = ausgabe;

            del.BeginInvoke(text, new AsyncCallback(_AsyncCallback), null);
        }

        private void _AsyncCallback(IAsyncResult ergebnis)
        {

        }

        private void ausgabe(string text)
        {
            tb.Text = text;
        }
    }
}

Leider erscheint der übergebene Text in Zeile 18 nicht in der TextBox! Zu einem Fehler kommt es aber auch nicht.

Kannst Du mir das bitte verständlich erklären?
 
Grantig schrieb:
Eigentlich müsste eine InvalidOperationException geworfen werden, weil nur der Thread der eine bestimmte Komponente erstellt hat auf sie zugreifen darf.
Tut sie auch, allerdings wird die Exception (weil sie im anderen Thread fliegt) erst beim Aufruf von "EndInvoke()" geworfen. Darum sieht man auch nichts.
 
Zurück
Oben