Netzwerk-Server Form friert ein

  • C#

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von SplittyDev.

    Netzwerk-Server Form friert ein

    Hi,

    ich hab ma ne frage und zwar hab ich einen Netzwerk-Server der nachrichten empfängt und weiterleitet, das ganze läuft über ne while-Schleife.

    Wenn ich den Server starte funktioniert er auch Richtextboxen werden gefüllt usw nur kann ich keine Buttons mehr drücken.
    Was ich aber brauche zum schließen der Form, was ich mir nun gedacht hatte war eine zweite Form zu erstellen und die Anwendung über die dann zu schließen, aber die friert auch ein.

    Jemand ne Idee oder eine andere Lösung?
    Du solltest die Vorteile von Multithreading nutzen.

    Deine while-schleife arbeitet im main-thread deiner anwendung,
    somit kann deine Form auf nichts mehr reagieren.

    Lagere die while-schleife in einen neuen Thread aus und invoke dann die RichTextBox, um sie zu befüllen.
    So bleibt die Form responsiv und du kannst sie immernoch benutzen.

    Falls du damit garnicht klarkommst kannst du am anfang oder am ende der while-schleife Application.DoEvents() aufrufen,
    das arbeitet die Nachrichtenschleife ab und die form bleibt einigermaßen responsiv.
    Das ist aber eine sehr unsaubere Lösung, sieh dir lieber das mit dem Multithreading an :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „SplittyDev“ ()

    soo, ich dachte grade ich hätts hinbekommen, allerdings klappts nich ganz so:

    Quellcode

    1. Thread accepting_clients;
    2. private void Form1_Load(object sender, EventArgs e)
    3. {
    4. ThreadStart accept_clients = new ThreadStart(client_accept);
    5. accepting_clients = new Thread(accept_clients);
    6. accepting_clients.Start();
    7. }


    und das hier in der funktion:

    Quellcode

    1. private void client_accept()
    2. {
    3. if (txtmessage.InvokeRequired)
    4. {
    5. txtmessage.Invoke(new MethodInvoker(client_accept));
    6. }
    7. if (button1.InvokeRequired)
    8. {
    9. button1.Invoke(new MethodInvoker(client_accept));
    10. }
    11. //...
    12. }


    Der Thread wird zwar gestartet, klappt auch alles. Aber die Form friert trotzdem ein.
    Mach ich was falsch?
    Im Thread muss nicht nur der Zugriff auf die Steuerelemente stattfinden,
    die komplette while-schleife muss in den Thread ausgelagert werden.

    Das könnte ungefähr so aussehen:

    C#-Quellcode

    1. private void Form1_Load (object sender, EventArgs e)
    2. {
    3. Thread accept_clients = new Thread (() =>
    4. {
    5. while (...)
    6. {
    7. ... // Die Nachrichten des servers behandeln
    8. // Auf die Form invoken
    9. Form1.Invoke (() =>
    10. {
    11. txtmessage.Text = "test"; // Text der txtmessage festlegen
    12. // Der Button wird von der form behandelt, das muss hier nicht getan werden.
    13. });
    14. }
    15. });
    16. accept_clients.Start ();
    17. }


    Sollten keine Fehler drin sein, wenn doch, sollten sie leicht zu beheben sein.

    Goldwing Studios schrieb:

    nachrichten verschicken ist automatisiert(wird nur ein einfacher Text zurück gesendet) und das annehmen von verbindungen und das anzeigen von eingehenden Nachrichten sind eine schleife


    Du musst die Schleife, die das annehmen der verbindungen übernimmt, in den Thread packen.

    Ich versuche mal, dir zu veranschaulichen, warum die Form einfriert.

    Du hast eine Form.
    Sehr stark vereinfach funktioniert eine Form so:
    Form <----> Message Queue <----> Windows

    Wenn du eine while-schleife benutzt, die niemals endet, passiert folgendes:
    Form -----> While-Schleife |----< Message Queue <----> Windows

    Deine Form kann sich also nichtmehr updaten und friert ein, während die While-schleife noch arbeitet.


    Beheben kannst du dies nur, indem du die while-schleife in einen neuen Thread verlagerst.

    Quellcode

    1. Form <----> Thread <----> Message-Queue <----> Windows
    2. |-> While-Schleife


    Grüße :thumbsup:
    Das Thema ist zwar schon geschlossen, aber um das problem mit dem späteren anzeigen der form zu beheben sollte es genügen, ein einfaches Form1.Show (); an den anfang der Form1_Load methode zu packen :D

    Hat bei mir immer funktioniert, schien auch die einfachste Lösung da ich meist zu faul war, herauszufinden an was das eigentlich liegt ;)