Autor Beitrag
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Do 15.12.11 20:34 
Hey Leute,

ich habe mal wieder eine Frage: Wie kann ich aus meiner Form ein Control entfernen dass mit Multithreading arbeitet? Wenn möglich ohne extra eine Methode zum herunterfahren aufrufen zu müssen.
Ich habe es mittels des Disposed Events probiert. Aber dies wird nicht aufgerufen wenn ich das Control entferne (mit Controls.Remove(xyz)) und auch nicht wenn ich vorher die Dispose()-Methode direkt aufrufe.

Hat jemand eine Idee?

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 15.12.11 21:34 
Hallo C#,

der Aufruf mit Controls.Remove() reicht aus, um das Control aus der Collection (und vom Bildschirm) zu löschen. Ein Aufruf mit Dispose() nachher ist nicht unbedingt notwendig (denn wenn der GC dann das Control abräumt - solange es nicht noch irgendwo anders referenziert wird - ruft es dann automatisch intern die Dispose()-Methode auf).

Wie genau rufst du denn die Remove-Methode auf? Und um was für ein Control handelt es sich?

Aber was genau meinst du mit "Control arbeitet mit Multithreading", denn WinForms-Controls sind nur im GUI-Thread benutzbar (und demnach NICHT multithreading-fähig).
C# Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Sa 17.12.11 19:09 
Das Control hab ich selbst gemacht (ich nenne es jetzt mal "ObservingBrick"). Es ist eine Klasse die als Interface ein Panel benutzt. Und dort arbeite ich eben mit Multi-Threading. Meine WinForm beinhaltet ein FlownLayoutPanel, dass eine unbestimmte Anzahl von ObservingBricks.

Der ObservingBrick hat unteranderem ein Button mit dem Text "Löschen". Und nun rufe ich in meiner WinForm das DeleteBut.Click()-Ereignis ab.
In dieser Methode wird dann auch der ObservingBrick aus dem FlownLayoutPanel entfernt aber wenn ich dann die Anwendung schließe, schließt sich zwar das Fenster aber die Threads meiner gelöschten ObservingBricks sind immer noch aktiv wenn ich das richtig gesehen habe.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 18.12.11 11:25 
Hallo,

bezogen auf deine Threads: verwendest du denn Vorder- oder Hintergrundthreads (s. Thread.IsBackground-Eigenschaft?
Per Default ist IsBackground auf 'false' gesetzt, d.h. ein Vordergrundthread. Und nur Hintergrundthreads (d.h. IsBackground = true) verhindern, daß der Hauptprozess sich beendet.

Trotzdem kommt mir das Arbeiten mit Controls und Multithreading bei dir etwas komisch vor.
Könntest du mal deine relevanten Teile der ObservingBrick-Klasse mal zeigen (d.h. Klassenkopf, Konstruktor sowie den Thread.Start und die relevanten Teile der Hauptschleife deines Threads).

Oder noch besser gefragt, was soll die ObservingBrick-Klasse denn leisten?
C# Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: So 18.12.11 12:06 
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
public Motor(...)
            {
                // ...
                nxtObserver = new Thread(NxtObserving);
                propertyObserver = new Thread(PropertyObserving);
                // ...
                nxtObserver.Start();
                propertyObserver.Start();
                threads = new List<Thread> { nxtObserver, propertyObserver };
            }


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
private void PropertyObserving()
while (!Disposing && !Closed)
                {
                    //try
                    //{
                        NameBox.Text = LocalName;
                        PortBox.Text = Port.ToString().Remove(0,4);
                        if (Observe && !nxtObserver.IsAlive)
                        {
                            threads.Remove(nxtObserver); 
                            nxtObserver = new Thread(NxtObserving); 
                            nxtObserver.Start();
                            threads.Add(nxtObserver);
                        }
                        if (ManualUpdating && Observe) ManualUpdating = false;
                        if (ManualUpdating != manualUpdateCache && ManualUpdating)
                          { Size = bigBox; Controls.Add(UpdateButton); manualUpdateCache = ManualUpdating; }
                        else if (!ManualUpdating)
                          { Size = smallBox; Controls.Remove(UpdateButton); manualUpdateCache = ManualUpdating; }
                    //}
                    //catch (Win32Exception) {}
                    //catch (Exception ex) { MessageBox.Show(ex.Message + "\n\n" + ex.TargetSite, "ERROR"); return; }
                }
}

So sieht das ganze aus. Der andere Thread hat die gleiche While-Schleife, ist aber ansonsten noch leer.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 18.12.11 12:48 
Hallo C#,

das habe ich mir fast schon so gedacht.

Führt denn nicht alleine schon NameBox.Text = LocalName; zu einer InvalidOperationException ("Der Zugriff auf das Steuerelement Steuerelementname erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde")? Oder hast du etwa CheckForIllegalCrossThreadCalls = false gesetzt??? Das ist ganz und gar nicht zu empfehlen!!!

Lies dir mal die Artikel Gewusst wie: Threadsicheres Aufrufen von Windows Forms-Steuerelementen und Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) gründlich durch...

Und der Sinn für die vielen Threads hat sich mir immer noch nicht erschlossen.
Wenn du mit WinForms etwas nebenläufig ausführen willst, dann benutze besser die Klasse 'BackgroundWorker' (da diese die Synchronisation mit dem GUI-Thread automatisch macht, d.h. in den Ereignissen ProgressChanged und RunWorkerCompleted).
C# Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: So 18.12.11 14:11 
Ok. Ich probier zukünftig mal Backgroundworker. Aber ich hab sowieso ne andere Lösung gefunden. Die Library die ich eingebunden hab stellt ein Event dafür bereit was ich machen will.
Tortzdem danke, ich werde mir den Artikel durchlesen.
Ich bin übrigends immer für Verbesseringsvorschläge offen.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 18.12.11 14:41 
Das ist sehr gut, denn dies sehe ich als Grundvoraussetzung für einen guten Entwickler ;-)
C# Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: So 18.12.11 14:45 
Sehr gut ;). Ich hab nämlich vor nach meiner Ausblidung Informatik zu studieren.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler