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
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
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 👍
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
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
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 😉
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.
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
ich habe jetzt eine Lösung gefunden mit der mehrere (Zeichen)Threads und Mdi-Anwendung zusammen funktionieren 🤔:
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:
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
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
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(
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.
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
das mit dem ein und aushängen des Mdi Fensterst hat auch nichts mit den mehreren Threads zu tun.