tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
9
ZUGRIFFE
1589
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von kuhlmaehn
    kuhlmaehn kuhlmaehn ist offline Mitglied Platin
    Registriert seit
    May 2003
    Beiträge
    634
    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?
    Danke!
     

  2. #2
    Avatar von FwDonnerbalken
    FwDonnerbalken FwDonnerbalken ist offline Mitglied Brokat
    Registriert seit
    May 2005
    Beiträge
    323
    Moin,

    die Idee mit dem Thread ist doch vernünftig. Der Zugriff auf die Windows-Steuerelemente aus dem Thread heraus funktioniert mit der Invoke-Methode.
    In der MSDN gibts einen Artikel mit einem nachvollziehbarem Beispiel dazu; schau mal hier: http://msdn2.microsoft.com/de-de/library/ms171728.aspx
     
    Gruß,
    Sebastian

    Mein XING Profil

    Hilfreiche Antworten bitte bewerten!

  3. #3
    Avatar von kuhlmaehn
    kuhlmaehn kuhlmaehn ist offline Mitglied Platin
    Registriert seit
    May 2003
    Beiträge
    634
    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:
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    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?
    Geändert von kuhlmaehn (10.04.08 um 17:39 Uhr)
     

  4. #4
    Avatar von Nico Graichen
    Nico Graichen Nico Graichen ist offline aka gemballa
    tutorials.de Moderator
    Registriert seit
    Dec 2003
    Ort
    Pulheim (NRW)
    Beiträge
    3.898
    Blog-Einträge
    34
    Hi

    Zitat Zitat von kuhlmaehn Beitrag anzeigen
    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
     
    Grüße Nico
    ----------------------
    Xing
    ----------------------
    Zitat Zitat von Mark Twain (1835-1910)
    Es gibt drei Dinge, die eine Frau aus dem Nichts hervorzaubern kann: einen Hut, einen Salat und einen Ehekrach.
    Zitat Zitat von Mike Wilson - Biographie über Larry Ellison (CEO Oracle)
    The Difference Between God and Larry Ellison: God Doesn't Think He's Larry Ellison

  5. #5
    Avatar von kuhlmaehn
    kuhlmaehn kuhlmaehn ist offline Mitglied Platin
    Registriert seit
    May 2003
    Beiträge
    634
    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.
     

  6. #6
    Avatar von FwDonnerbalken
    FwDonnerbalken FwDonnerbalken ist offline Mitglied Brokat
    Registriert seit
    May 2005
    Beiträge
    323
    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!
     
    Gruß,
    Sebastian

    Mein XING Profil

    Hilfreiche Antworten bitte bewerten!

  7. #7
    Avatar von kuhlmaehn
    kuhlmaehn kuhlmaehn ist offline Mitglied Platin
    Registriert seit
    May 2003
    Beiträge
    634
    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.
     

  8. #8
    Avatar von kuhlmaehn
    kuhlmaehn kuhlmaehn ist offline Mitglied Platin
    Registriert seit
    May 2003
    Beiträge
    634
    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
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    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.
    Geändert von kuhlmaehn (12.04.08 um 01:01 Uhr)
     

  9. #9
    Avatar von FwDonnerbalken
    FwDonnerbalken FwDonnerbalken ist offline Mitglied Brokat
    Registriert seit
    May 2005
    Beiträge
    323
    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.
     
    Gruß,
    Sebastian

    Mein XING Profil

    Hilfreiche Antworten bitte bewerten!

  10. #10
    Avatar von kuhlmaehn
    kuhlmaehn kuhlmaehn ist offline Mitglied Platin
    Registriert seit
    May 2003
    Beiträge
    634
    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..
    Geändert von kuhlmaehn (12.04.08 um 17:25 Uhr)
     

Ähnliche Themen

  1. Windows Form Anwendung
    Von MSVCplusplus im Forum C/C++
    Antworten: 16
    Letzter Beitrag: 18.02.11, 17:03
  2. Windows Explorer Ersatz
    Von Nino14 im Forum Microsoft Windows
    Antworten: 3
    Letzter Beitrag: 15.06.07, 17:31
  3. Windows Anwendung erstellen
    Von BillaBong im Forum C/C++
    Antworten: 1
    Letzter Beitrag: 04.04.07, 17:55
  4. Ersatz für Thunderbird (windows), oder andere kontenverwaltung
    Von Andreas Späth im Forum Internet, DSL & Flatrate
    Antworten: 0
    Letzter Beitrag: 19.03.07, 01:02
  5. Windows Anwendung schreiben
    Von Cora im Forum C/C++
    Antworten: 25
    Letzter Beitrag: 25.10.03, 18:23