Laden...

[erledigt] Multithreading im GUI: Wert eines Controls aus einem anderen Thread abfragen

Erstellt von exaveal vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.401 Views
E
exaveal Themenstarter:in
96 Beiträge seit 2010
vor 13 Jahren
[erledigt] Multithreading im GUI: Wert eines Controls aus einem anderen Thread abfragen

Hallo und frohes Neues.

Eigentlich wollte ich nicht auch noch mit Multithreading anfangen, aber durch die Nutzung von SQLDependencies bleibt mir jetzt nichts anderes übrig.

Mein Programm arbeitet mit einer SQL Datenbank im Hintergrund zusammen. Wenn sich in der Datenbank ein Datensatz ändert, wird ein Event ausgelöst, was meine folgende Klasse dazu bewegt, den Wert einer(seiner) Combobox auszulesen.


    public partial class ModuleSearchTabContent : TabContent
    {
        private ModuleSearch sourceModule;


        delegate string ComboBoxGetTextCallback(ComboBox sender);
        private string ComboBoxGetText(ComboBox sender)
        {
            // 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 (sender.InvokeRequired)
            {
                ComboBoxGetTextCallback d = new ComboBoxGetTextCallback(ComboBoxGetText);
                sender.Invoke(d, new object[] { sender });
                return ""; // richtig? Funktion wird ja eh neu aufgerufen, aber ein Rueckgabewert muss zurueck gegeben werden.
            }
            else
            {
                return sender.Text;
            }
        }


        public ModuleSearchTabContent()
        {
            InitializeComponent();

            sourceModule = new ModuleSearch();
            sourceModule.DBTableChanged += sourceModule_DBTableChanged;
        }


        private void sourceModule_DBTableChanged(object sender, SqlNotificationEventArgs e)
        {
//Aufruf der Funktion. gibt aber IMMER einen leeren String zurueck, obwohl in der Combobox ein Wert drin steht:
            Console.WriteLine("Wert ComboBox = " + ComboBoxGetText(combxCourseNr));
        }
    }

Die Methode private string ComboBoxGetText(ComboBox sender) gibt, wenn es durch das Ereignis aufgerufen wird, immer einen Leerstring zurück. Rufe ich aber die Methode über einen Button auf, funktioniert sie fehlerfrei.

Habe ich die get-Methode richtig implementiert? Wo liegt genau der Fehler? Ich habe mich an der Anleitung auf der MSDN orientiert:
Gewusst wie: Threadsicheres Aufrufen von Windows Forms-Steuerelementen

Vielen Dank für jede Hilfe!

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo exaveal,

nein, deine Get-Methode ist nicht richtig.
Du kontrollierst zwar ob du im richtigen Thread bist und rufst es auch mit Invoke auf, aber du gibst dann sofort "" zurück.

Deshalb erhälst du auch immer "" zurück.

Versuche mal den Rückgabewert von sender.Invoke(...) zurückzugeben.

Und guck mal hier: [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)
Ist auch ne nette Beschreibung zu dem Thema

Gruss
Michael

E
exaveal Themenstarter:in
96 Beiträge seit 2010
vor 13 Jahren

Hallo,
ja das war schon meine Vermutung.

Ich will nicht über eine "Notvariable" gehen. Ich werde deinen Link mal studieren.

Danke vorerst!

E
exaveal Themenstarter:in
96 Beiträge seit 2010
vor 13 Jahren

Dein Thread hat mir zwar nichts speziell zum Problem geholfen, aber trotzdem interessant.

Durch deine Stichwörter konnte ich aber die richtigen Suchbegriffe verwenden.

Meine Lösung:


        private string ComboBoxGetText(ComboBox sender)
        {
            if (sender.InvokeRequired)
            {
                ComboBoxGetTextCallback d = new ComboBoxGetTextCallback(ComboBoxGetText);
                return (string)this.Invoke(d, new object[] { sender });
            }
            else
            {
                return sender.Text;
            }
        }