Laden...

MdiFenster mit unterschiedlichen Threads

Erstellt von DerSchreiberling vor 15 Jahren Letzter Beitrag vor 15 Jahren 3.970 Views
D
DerSchreiberling Themenstarter:in
5 Beiträge seit 2008
vor 15 Jahren
MdiFenster mit unterschiedlichen Threads

Hallo Liebe C# Gemeinde,

ich muss folgendes realisieren:
Ein Mdi-Container soll auf Buttondruck neue Threads starten, diese Threads sollen neue Fenster erstellen und darstellen (das ganze hat den Hintergrund das die Applikation für Multicores optimiert werden soll).
Nun mache ich neue Threads die daraufhin eine Form erstellen. Leider funktioniert das nicht weil das Mdi-Parent nicht in einem anderen Thread liegen darf.
Soweit jedenfalls meine Nachforschungen. Aber wie kann ich das dan realisieren? (Mdi-Childs die mit eigenen Fensterthreads dargestellt werden...)

Hier noch der relevante Code:


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        CheckForIllegalCrossThreadCalls = false;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread NeuerThread = new Thread(new ParameterizedThreadStart(Form1.FensterErzeugen));
        NeuerThread.Start(this);
    }

    public static void FensterErzeugen(object mdiParent)
    {
        Form2 frm = new Form2();
        frm.MdiParent = (Form)mdiParent; //hier kommt eine Fehlermeldung
        frm.Show();
    }
}

Ich danke jetzt schon jedem Helfer!
Gruss DerSchreiberling

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo DerSchreiberling,

es stimmt, alle MdiFenster müssen in demselben Thread laufen.

Ist aber kein Problem. Du musst ja nur die eigentlichen rechenaufwändigen Teile in extra Threads verlagern. Siehe dazu [FAQ] Warum blockiert mein GUI?

herbivore

3.430 Beiträge seit 2007
vor 15 Jahren

Hi,

Und Herzlich Willkommen bei MyCsharp.de

Nun mache ich neue Threads die daraufhin eine Form erstellen. Leider funktioniert das nicht weil das Mdi-Parent nicht in einem anderen Thread liegen darf.

Eine Grundregel ist, dass man die gesamte GUI immer auf einen Thread lassen soll.
Das heisst: Kein Fenster oder Control mit anderen Threads erstellen.

Deshalb würde ich dir von diesem Vorhaben abraten.
Wenn du es für Multicore optimieren willst, dann kannst du ja die Berechnungen usw. auf mehrere Threads verteilen, aber die Gui würde ich auf einem Thread belassen.

Siehe dazu: [FAQ] Warum blockiert mein GUI?

mfg
michlG

//EDIT: Hebivore war wieder einmal schneller 👍

2.223 Beiträge seit 2005
vor 15 Jahren

Hallo derSchreiberling und Herzlich Willkommen,

Also um eine Anwendung für Multicores zu Optimieren packt man keine Gui Elemente in ein eigenen Thread sondern nur den machmal langläufigen Backend Code

mfg

M
47 Beiträge seit 2008
vor 15 Jahren

Hallo DerSchreiberling,

ich habe mich vor kurzem auch mit dem Thema auseinander gesetzt und nicht wirklich verstanden was die Jungs hier meinen.

Wenn man aber den von herbivore genannten link folgt und sich zu diesem Thema die Webcasts von Bernd Marquardt ansieht bekommt man ein gefühl für MultiThreading.

Gruß

MOGnew

D
DerSchreiberling Themenstarter:in
5 Beiträge seit 2008
vor 15 Jahren

Ihr seid ja ein echt tolles Forum. Soviele Antworten 🙂

ich bin nämlich Student in einem Ferienjob.
Die Aufgabe war es nun mehrere Fenster parallel neuzeichnen zu lassen.
Habe gemeint das geht nicht, weil ich beim googeln gelesen habe das alle im gleichen Thread laufen müssen. Mein Chef meinte das gehen muss...

Also wenn ich euch recht verstehe gibt es keine Möglichkeit das sich die Fenster gleichzeitig neuzeichnen, oder!?

Danke Leute!!! Sich als Praktikant durchzusetzen ist nicht so einfach 😉

M
47 Beiträge seit 2008
vor 15 Jahren

Hallo DerSchreiberling,

ich bin mir nicht sicher, aber ich denke diese Aussage macht keinen Sinn.
Das erzeugen mehrerer Forms dauert nicht lange. Viel wichtiger ist es, dass die Methoden welche extrem lange brauchen, in Threads ausgelagert werden.

Wenn diese Methoden dann wiederum auf das UI zugreifen, muss wie Bernd Marquardt sagt, "Die goldene Regel" beachtet werden.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo MOGNew,

Mein Chef meinte das gehen muss...

da hat er unrecht. Zumindest bei MDI.

Vielleicht hat er es mal unter .NET 1.1 zum Laufen bekommen, das kann sein, aber falsch wäre es auch da schon gewesen.

Aber noch mal: es ist ja auch gar nicht nötig. Also häng dich nicht daran auf. Wichtig ist., dass die rechenintensiven Operationen in unterschiedlichen Thread laufen.

herbivore

D
DerSchreiberling Themenstarter:in
5 Beiträge seit 2008
vor 15 Jahren

ich habe jetzt eine Lösung gefunden mit der mehrere (Zeichen)Threads und Mdi-Anwendung zusammen funktionieren 🤔:

  1. das Mdi erzeugt das childform und weisst das MdiParent zu.
  2. das Mdi erzeugt einen neuen Thread dem das childform übergeben wird.
  3. der Thread ruft Application.Run(childform) auf.

Funktionieren tuts jedenfalls problemlos.
Irgendwelche Einwände?

und schon habe ich eine neue Aufgabe:
die Childforms sollen sich ausdocken können und wieder eindocken können. Ausdocken ist kein problem (MdiParent = null). Aber beim eindocken hängts. Schließlich muss bei der MdiParent zuweisung beides in einem Thread sein...

Habe also folgenden Plan ausgetüfftelt:

  1. Das Childform sagt seinem Parent das es gleich sterben wird. Der Parent startet einen Thread der als Parameter den Form und den Thread in dem der Form läuft bekommt. Dieser Thread überwacht den Thread des Kindes.
  2. Das Kind beendet seinen Thread mittels Application.ExitThread.
  3. Der Überwachungsthread reagiert auf Threadende. Er setzt das MdiParent neu (dar beides in einem Thread ist) und startet für das Child wieder einen eigenen Thread der wiederrum Application.Run aufruft.

Sollte doch eigentlich klappen, oder? Tut es aber nicht. Der Überwachungsthread wartet braf bis der Childthread beendet ist. Komischerweise bricht der Überwachungsthread dan einfach zwischen folgenden Zeilen ab (ohne Fehlermeldung oder sonst irgendeiner Reaktion):


Thread NeuerThread = new Thread(new ParameterizedThreadStart(MDIParent1.CreateThread));
NeuerThread.Start(toReanimateForm);

C# ist schon eine Sache für sich. Aber der GarbageCollector hat mich überzeugt 😉

Gruß DerSchreiberling

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo DerSchreiberling,

Irgendwelche Einwände?

ja, es wundert mich, dass das funktioniert. Zumindest hat es nicht den gewünschten Effekt. Auch wenn das Application.Run in dem anderen Thread läuft, bekommt das Fenster seine Nachrichten nicht von dort. Ein Fenster bekommt seine Nachrichten immer aus dem Thread aus dem es erzeugt wurde.

Alle Mdi-Fenster müssen in einem Thread laufen. Alles andere macht früher oder später Problem.

Insofern entfällt dein weitergehende Frage, weil sie ja auf der Annahme basiert, dass mehrere Threads verwendet werden.

herbivore

915 Beiträge seit 2006
vor 15 Jahren

Hrm, nur so ne Frage? - Wenn dein Cheff meint das du dass so machen musst. Was ist dann das Ziel - sollen die MDI Fenster später aus dem MDIParent herausgezogen werden können um sie auf ein anderes Programm drauf zu setzen? Denn nur dann würde ich den Sinn dahinter erkennen, da SetParent für diesen Vorgang alleinig nicht ausreichen würde und du wirklich eigene GUI Threads benötigst.

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

D
DerSchreiberling Themenstarter:in
5 Beiträge seit 2008
vor 15 Jahren

das ganze ist nur als Usability-Feature gedacht. So kann man das Hauptfenster minimieren und das andere Fenster trotzdem weiterverwenden oder es zB. auf einen anderen Bildschirm rüberschieben.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo DerSchreiberling,

dazu müssen die Fenster nicht in unterschiedlichen Threads laufen. Es sollte reichen, MdiParent auf null zu setzen.

Alle Mdi-Fenster müssen in einem Thread laufen. Alles andere macht früher oder später Problem.

herbivore

D
DerSchreiberling Themenstarter:in
5 Beiträge seit 2008
vor 15 Jahren

das mit dem ein und aushängen des Mdi Fensterst hat auch nichts mit den mehreren Threads zu tun.