[C#] While-Ersatz für Windows-Anwendung

kuhlmaehn

Erfahrenes Mitglied
Hi!
Auf den ersten Blick geht es zwar um eine Schleife allerdings brauche ich diese im Zusammenhang mit dem TcpClient darum ist die Frage hier hoffentlich richtig :)
Und hab ich eine Konsolenanwenung wo ein Client mit einer Whileschleife dauerhaft Daten von einem Server empfängt. Soweit so gut..
Jetzt will ich das alles aber in einer Windows-Anwendung haben und glaube das hier eine Whileschleife nicht der richtige Weg ist. Ich hab zwar schon probiert sie mit einem Thread lauffähig zu machen aber das hat nicht befriedigend geklappt :(
Danach hab ich es dann mit einen Timer probiert aber der hat die Form auch einfrieren lassen. Außerdem ist das Problem, dass ich den TcpClient schon bei Form_Load starte und dann mit dem Timer nicht mehr auf ihn zugreifen kann. In einem Thread kann ich dagegen nicht auf Steuerelemente zugreifen :(
Ich suche also eine Lösung wie ich alles in einer Funktion starten kann. Also quasi einen Timer, der beim ersten mal den Clienten initialisiert und danach aber nur noch benutzt (oder so).
Oder wie sollte ich das am besten machen? :confused:
Danke!
 
Mh danke erstemal, dass hatte ich so schonmal kurz probiert und hab dann in dem Thread halt weiterhin die Whileschleife laufen lassen. Aber nach dem starten hat sich das Programm trotzdem aufgehängt bzw. ist sehr stockend gelaufen.
Ist eine Whileschleife (mit while(true) hab ich das gemacht) vielleicht einfach zu "aggressiv" für eine Windows-Anwendung oder sollte das klappen?
Kann ich vielleicht dem Thread sagen mach irgendwas so oft wie es geht ohne das es laggt?

[Edit]
Passt zwar nicht mit richtig hier rein aber ich hab mal dieses Beispiel getestet und es klappt nicht:
C#:
private void Form1_Load(object sender, EventArgs e)
        {
            Thread MyNewThread = new Thread(new ThreadStart(ThreadProc));

            MyNewThread.Start();
            MyNewThread.Join();
        }

protected static void ThreadProc()
        {
            while (true)
            {
            
            }
        }
Scheint nicht zu klappen mit einer While-Schleife. Warum? :(
 
Zuletzt bearbeitet:
Hi

Ist eine Whileschleife (mit while(true) hab ich das gemacht) vielleicht einfach zu "aggressiv" für eine Windows-Anwendung oder sollte das klappen?
Eine Schleife der Art While(true) ist nicht nur für WinApps "aggressiv", wie du es ausdrückst, so was ist generell gefährlich. Du erzeugst damit unkontrolliert Last im Prozessor. Die Bedingung der Schleife erreicht ja nie den Wert False.

Poste doch auch mal den Code, den du in der Schleife ausführen willst.
Falls du etwas immer wiederkehrend ausführen willst, ist z.B. ein Timer kein schlechtes Hilfsmittel ;)

@Sebastian
Grüße, lange nicht gesehen :)
 
Ich hab den ganzen Code leider gerade nicht hier aber es ist eine Konsolenanwendung und es wird halt in der Schleife jedes mal geguckt ob "exit" eingegeben wurde und dann beendet es.
Bei dem Timer hatte ich halt das Problem, dass der TcpClient dann ja bei jedem "Event" neu gestartet wird weil wenn ich ihn bei Form_Load starte kennt der Timer den TcpClienten nicht.
 
Ich verstehe den Gesamtzusammenhang leider noch nicht so ganz, vor allem nicht, was du in einer Konsolenanwendung mit ner Form willst.

Ich versuche das aber mal zu verstehen und einen Tipp zu geben:
Offensichtlich willst du eine Konsolenanwendung schreiben, die Daten empfängt, die soll solange laufen, bis der User das ganze durch die Eingabe von exit abbricht.

Dann mach die Sache doch folgendermaßen. Für den Thread implementierst du die Logik des Empfangens. Das Hauptprogramm startet diesen Thread und stellt eine Eingabeaufforderung bereit für den Programmabbruch. Sobald eine entsprechende Eingabe erfolgt ist setzt du einen bool, der vom Thread bei jeden Durchlauf abgefragt wird, optimalerweise in der while-Schleife (hier ist sie wieder ;))
Sobald der bool gesetzt wurde sollte der Thread in Kürze beendet werden, auf dieses Ende wartet das Hauptprogramm mit Thread.Join(), und aus die Maus!
 
Ach sorry, da hab ich Unsinn geredet. (Kommt davon wenn man mit Angst postet beim Surfen erwischt zu werden ;))
Also eigentlich lief das ganze in einer Konsole in einer Whileschleife, die unterbrach wenn "exit" eingeben wird.
Jetzt will ich aber weg von der Konsol hin zur Windowsanwendung. Hierfür brauch ich das mit dem "exit" natürlich nicht mehr aber ich dachte vielleicht frag ich immer eine Variable ab und wenn diese "False" ist wird die Schleife unterbrochen.
ich brauch also gar nichts mehr mit Konsole da hab ich wie gesagt Mist geredet. :)
Eigentlich finde ich die Lösung unten mit dem Thread und der Whileschleife ja gut nur es funktioniert halt leider nicht :)
Hoffentlich hab ich mich jetzt klarer ausgedrückt und in deiner Antwort hoffentlich nichts übersehen.
 
Ach man, jetzt dachte ich ich hätte endlich eine Lösung aber das klappt auch wieder nicht :(
Ich dachte ich mach das jetzt so das ich einen String hab und wenn der auf "true" steht wird im Timer der TcpClient gestartet und am ende der String auf "false" gesetzt. Ab dann wird im Timer nur noch das Abrufen gemacht. Nur dummerweise kennt dann C# in der else-Schleife den Client nicht.
Hier mal der Code
C#:
String start = "true";
        byte[] data = new byte[1024];
        string input, stringData;
        Byte[] send1 = System.Text.Encoding.ASCII.GetBytes("hallo");

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (start == "true")
            {
                TcpClient server = new TcpClient("127.0.0.1", 1234);

                NetworkStream ns = server.GetStream();

                ns.Write(send1, 0, send1.Length);

                int recv = ns.Read(data, 0, data.Length);
                stringData = Encoding.ASCII.GetString(data, 0, recv);
                listBox1.Items.Add(stringData);
                start = "false";
            }
            else if (start == "ende")
            {
                ns.Close();
                server.Close();
            }

            else 
            {
                data = new byte[1024];
                recv = ns.Read(data, 0, data.Length);
                stringData = Encoding.ASCII.GetString(data, 0, recv);
                listBox1.Items.Add(stringData);
            }
        }
Ich weiß einfach nicht wie das gehen soll, dass der Client nur einmal initialisiert wird und danach trotzdem noch auf ihn zugegriffen werden kann..

Das was im else steht soll quasi immer ausgeführt werden nachdem dem Server "hallo" gesendet wurde, weil dieser dann in unregelmäßigen Abständen etwas sendet.
 
Zuletzt bearbeitet:
Du deklariert die Variable server innerhalb des if-Blocks zwischen den geschweiften Klammern. Diese Variable ist damit nur in diesem Block gültig und außerhalb unbekannt.

Du musst die Variable Server auf der Ebene der Form-Klasse deklarieren (so wie die Variable start, die du nebenbei gesagt besser als bool deklarierst), das gleiche gilt auf für den NetworkStream.
 
Achso ich deklariere ihn außerhalb und kann ihn dann zB in Form_Load starten und im Timer benutzen!? Das ist ja genau das was ich gesucht hab und so einfach ^^
Ich dacht ich hätte das so schon probiert und es ging nich aber da hab ich wohl was falsch gemacht.
Danke dir :)
Ich hatte start erst als bool aber ich brauchte dann ja 3 "Zustände" und dann hab ich halt ein String draus gemacht :)

[Edit]
Ja funktioniert jetzt super, komisch ich dacht ich hätte das ausgeschlossen gehabt..
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück