Entwickler-Ecke

C# - Die Sprache - Schleife bricht mit zwei Bedingungen nicht ab


SiickneZz - So 10.09.17 20:45
Titel: Schleife bricht mit zwei Bedingungen nicht ab
Hallo,

ich will eine Schleife schreiben die abbricht, wenn entweder die "Enter" Taste gedrückt wird oder eine Anzahl an Millisekunden vergangen ist.
Ich habe beides einzeln bereits versucht und das hat auch funktioniert allerdings wenn ich beides verschmelze funktioniert es nicht mehr.



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
static internal void Stopp(string Meldung, int Msek)
        {
            Msek = 3000//Testwert
            int abbruch = Environment.TickCount + Msek;
            Console.WriteLine($"{Meldung} \n\t - Return Taste - oder {Msek} Millisekunden ({(double)Msek / 1000} Sekunden) warten!");
            //while (Console.ReadKey().Key != ConsoleKey.Enter && abbruch > Environment.TickCount) { }  // Bricht nur bei Enter ab

            //while (true) { if (abbruch < Environment.TickCount) { return; } }                  // Nur zum Test, Bricht nach x msek ab

            while (Console.ReadKey().Key != ConsoleKey.Enter ) { if (abbruch < Environment.TickCount) { return; } } // Bricht nur bei Enter ab
        }


Vielen Dank für eure Hilfe!


Palladin007 - So 10.09.17 21:23

Dein Problem ist, dass die while-Schleife nicht wirklich läuft.
Die fragt in der Bedingung immer einmal nach einem Tastendruck.
Dein Code würde wahrscheinlich funktionieren, wenn Du immer eine andere Taste drückst - nicht die Enter-Taste.

Wenn Du dieses Verhalten nicht haben willst, brauchst Du einen zweiten Thread, der die while-Schleife ausführt.
Die Main-Thread teilt dem zweiten Thread dann mit, dass er sich beenden soll.
Ein paar Suchbegriffe dazu: Task, async, await, CancellationToken


Aber ein Tipp wegen deinem Versuch mit Environment.TickCount: Stopwatch [https://msdn.microsoft.com/de-de/library/system.diagnostics.stopwatch(v=vs.110).aspx]
Die Klasse ist eine Stopuhr, die macht genau das, was Du haben willst: Zeit messen


C#-Quelltext
1:
2:
3:
4:
var watch = Stopwatch.StartNew();

while (watch.ElapsedMilliseconds < 3000)
    Thread.Sleep(10);


Th69 - Mo 11.09.17 09:16

Hallo und :welcome:

solange keine Taste gedrückt wird, blockiert Console.ReadKey [https://msdn.microsoft.com/de-de/library/471w8d85(v=vs.110).aspx]. Mittels der Eigenschaft Console.KeyAvailable [https://msdn.microsoft.com/de-de/library/471w8d85(v=vs.110).aspx] kann man aber vorher abfragen, ob eine Taste gedrückt wurde.