Laden...

Delay in C#

Erstellt von jofenchel vor 18 Jahren Letzter Beitrag vor 15 Jahren 14.055 Views
jofenchel Themenstarter:in
117 Beiträge seit 2005
vor 18 Jahren
Delay in C#

Hallo zusammen,

gibt es C# sowas aenliches wie Delay()?

Ich mochte in einer Schleife eion Delay einbauen um z. B. eine Progressbar zu testen.

Ich weiss ich koennte auch mit einem Timer arbeiten, was eventuell besser waere.
Aber ich wurde gerne wissen ob es sowas gibt.

Danke fuer eure Tips.

Gruss
JoFenchel

1.549 Beiträge seit 2004
vor 18 Jahren

wäre vieleicht interesant zu wissen was den Delay machen soll über google bin ich nämlich nicht drauf gekommen

Wir Arbeiten eigendlich nicht wir nehmen nur das geld

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo jofenchel,

Thread.Sleep.

Allerdings ist die Oberfläche blockiert, solange du in der Schleife bist und sie wird auch nicht aktualisiert. Du könntest bei jedem Schleifendurchlauf DoEvents benutzen, um das Problem zu entschärfen. Die Oberfläche ist dann aber immer noch jeweils solange blockiert, wie du schläfst. Aber für den Test sollte es reichen.

Hallo S.H.-Teichhof,

http://dict.leo.org hätte in diesem Fall wohl mehr geholfen als google 🙂

herbivore

P
172 Beiträge seit 2005
vor 18 Jahren

Gibts denn eigentlich keine Möglichkeit die Oberfläche dabei nicht zu blockieren?

1.549 Beiträge seit 2004
vor 18 Jahren

doch die arbeit in einen seperaten Thread auslagern und diesen dann anhalten

Wir Arbeiten eigendlich nicht wir nehmen nur das geld

Q
992 Beiträge seit 2005
vor 18 Jahren

Ich glaube nur um ne progressbar zu testen ist es egal, ob Du dabei den GUI-Thread blockierst.
Wenn Du das produktiv in einem Programm einsetzen willst, dann nehm eine der drei Timer-Klassen.

563 Beiträge seit 2004
vor 18 Jahren

oder in 2.0 benutzst du den BackgroundWorker

S
34 Beiträge seit 2005
vor 18 Jahren

Hallo,

habe ein ähnliches Problem, benötige auch eine "zeitliche Pause", in welcher jedoch die für den Benutzer sichtbare Oberfläche aktualisiert werden soll.

Mich bringen keine der bisher gefundenen Möglichkeiten weiter, allerdings bin ich auch noch blutiger Anfänger, vielleicht kann mir hier jemand noch einen Tipp geben?

Danke schonmal im Voraus. =)

'Ich sag ja immer: "Wer nicht mit der Zeit geht, der muss halt mir der Zeit gehen ne...!"'

jofenchel Themenstarter:in
117 Beiträge seit 2005
vor 18 Jahren
Delay

Hallo zusammen,

das Delay soll mir nur ermoeglichen eine Progressbar zu testen.
Ich habe mehrere zur Auswahl aber die Optik ist immer anders.
Nun will ich mir die passende aussuchen bei der die Programmierung und die Optik am besten ist.
Das ganze lasse ich dann in einer Schleife laufen.

Hi .unreal: Was genau ist und macht der BackgroundWorker?
Ich habe noch 1.1 installiert.

Aber ich denke das ich doch mit Timern testen werde.
Ich sollte nur mehr ueber die TimerKlassen wissen.
Werde da mal das Forum durchforsten.

Gruss
JoFenchel

4.221 Beiträge seit 2005
vor 18 Jahren

Nur für einen Test müsste folgendes reichen...

Thread.Sleep(1000); //paust 1 Sekunde
Application.DoEvents(); // Events abarbeiten (damit das UI nicht einfriert)

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

S
34 Beiträge seit 2005
vor 18 Jahren

Auch wenns vielleicht nicht für mich gedacht war, hat mir super weitergeholfen Programmierhans. Vielen Dank! 🙂

'Ich sag ja immer: "Wer nicht mit der Zeit geht, der muss halt mir der Zeit gehen ne...!"'

4.221 Beiträge seit 2005
vor 18 Jahren

Original von sublime
Auch wenns vielleicht nicht für mich gedacht war, hat mir super weitergeholfen Programmierhans. Vielen Dank! 🙂

Wem's nützt für den isses 😁

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

563 Beiträge seit 2004
vor 18 Jahren

Original von Programmierhans
Nur für einen Test müsste folgendes reichen...

Thread.Sleep(1000); //paust 1 Sekunde
Application.DoEvents(); // Events abarbeiten (damit das UI nicht einfriert)

wenn man

Thread.Sleep(10000);
++i;

machen würde, dann würde das ++i erst stattfinden, wenn der thread 10000 ms gesleept hat. warum ist das bei Application.DoEvents(); nicht so?

4.221 Beiträge seit 2005
vor 18 Jahren

Thread.Sleep legt den Thread schlafen.....

DoEvents hingegen zieht die nächste Message des MessageLoops und beginnt diese zu verarbeiten.... (z.B: eine Message dass irgendwas neu gezeichnet werden muss)....

Wenn du z.B: in einem Click ein DoEvents reinhaust und dann wie wild auf dem Button rumdrückst bringst Du es fertig, dass der Code in eine Methode (EventHandler) reinläuft obwohl er dort schon drin ist.....

Dieses reentrant-Problem kann voll tödlich sein, da man dieses nicht mit einem Lock oder Mutex blocken kann (es läuft ja ebenfalls im UI-Thread ab)....

DoEvents ist somit IMMER mit höchster Vorsicht zu geniessen.

--> eine Boardsuche "reentrant" sollte noch ein paar interessante Darstellungen dieses Problems an's Licht bringen.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo jofenchel,

Gibts denn eigentlich keine Möglichkeit die Oberfläche dabei nicht zu blockieren?

Nein, man kann unter Windows nur blockierende Oberflächen schreiben. 🙂 Davon abgesehen blockiert meine Lösung ja immer nur so kurz, dass es für den Test reicht.

Hallo sublime,

Auch wenns vielleicht nicht für mich gedacht war, hat mir super weitergeholfen Programmierhans.

genau das, was Programmierhans als Code geschrieben hat, stand bei mir oben im Text. Sicher kann man mal was übersehen, aber hier hat es mich schon verblüfft.

Hallo .unreal,

wenn man Thread.Sleep(10000); ++i; machen würde, dann würde das ++i erst stattfinden, wenn der thread 10000 ms gesleept hat. warum ist das bei Application.DoEvents(); nicht so?

Das ist bei DoEvents genauso. Das DoEvents wird erst ausgeführt, wenn das Sleep vorbei ist. Das weitere hat Programmierhans schon beschrieben.

herbivore

T
111 Beiträge seit 2005
vor 18 Jahren

Hallo

was würde passieren, wenn ich das Delay folgender weise erstelle:



for (i=1; i<=1000; i++)
{
    Thread.Sleep(1);
    Application.DoEvents();
}

Dies sollte doch eigentlich eine Pause von 1 Sekunde erzeugen, das Programm aber nicht blockieren (ich mache dies in Delphi zumindestens so)

mfG Thomas

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo thomas.at,

in C# musst du die Zeit in Millisekunden angeben, also 1000 für eine Sekunde. Das Programm ist dann jeweils auch für eine Sekunde blockiert.

herbivore

4.221 Beiträge seit 2005
vor 18 Jahren

Original von herbivore
Hallo thomas.at,

in C# musst du die Zeit in Millisekunden angeben, also 1000 für eine Sekunde. Das Programm ist dann jeweils auch für eine Sekunde blockiert.

herbivore

1000 Durchläufe a 1 Milli (theoretisch 😉) ergibt auch ne Sekunde ... und dem Prozessor wird's garantiert nicht langweilig 🤔

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Programmierhans,

oh, so hatte ich das gar nicht verstanden. Aber das kommt natürlich überhaupt nicht hin, weil es ja stark von der Zeit abhängt, die für die Thread-Wechsel (ausgelöst durch das Thread-Sleep) und die DoEvents benötigt wird. Außerdem wird - wie du schon sagst - vermutlich heftig Prozessorlast erzeugt. Ist auf jeden Fall keine gute Methode. Für diesen Fall würde ich einen Timer verwenden.

herbivore

4.221 Beiträge seit 2005
vor 18 Jahren

Oder so 🙂



	public class MethodsWhoNoOneNeeds
	{
		public static void Block(TimeSpan pTimeToBlock)
		{
			DateTime dtStart=DateTime.Now;
			while(dtStart+pTimeToBlock>DateTime.Now)
			{
				Application.DoEvents();
			}
		}
	}


Ganz ohne Thread.Sleep.... da ruckelt auch nix 🙂 aber der Prozessor wird auf 100% sein nehme ich an.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

jofenchel Themenstarter:in
117 Beiträge seit 2005
vor 18 Jahren

Hallo Programmierhans,

deinen Vorschlag habe ich ausprobiert.
Geht leider nicht. Bei mir ist dann das ganze System tot.
Musste danach meinen Laptop neu boote.


Thread.Sleep(1000); //paust 1 Sekunde
Application.DoEvents(); // Events abarbeiten (damit das UI nicht einfriert) 

JoFenchel

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo jofenchel,

das kann eigentlich nicht an den beiden Zeilen liegen. Die Anweisungen sind ok. Und selbst wenn du durch ein langes Sleep deine ganze Anwendung blockierst, sollte dadurch nicht das Betriebssystem blockiert werden (oder hast du Windows ME?).

Auch irgendwelcher Mist, den du in deinem Programm machst, sollte nicht diese Auswirkung haben können. Ich würde das erstmal für ein zufälliges Zusammentreffen halten oder für ein grundsätzliches Problem deines Betriebssystems.

herbivore

563 Beiträge seit 2004
vor 18 Jahren

Original von jofenchel
Hallo Programmierhans,

deinen Vorschlag habe ich ausprobiert.
Geht leider nicht. Bei mir ist dann das ganze System tot.
Musste danach meinen Laptop neu boote.

  
Thread.Sleep(1000); //paust 1 Sekunde  
Application.DoEvents(); // Events abarbeiten (damit das UI nicht einfriert)   
  

JoFenchel

das funktioniet doch nicht, weil der zuesrt sleept, und dann das gui aktualisiert, somit ist das gui auch ne sekunde gefreezed...

S
34 Beiträge seit 2005
vor 18 Jahren

Hallo herbivore,

sorry habs nochmal nachgeguckt und du hattst schon recht, dass der Tipp in deinem Post derselbe war wie von Programmierhans, habs anfangs auch damit probiert, aber das dann noch mit Teilen aus der MSDN vermischt und dadurch gings net. Stand einfach ein wenig aufm Schlauch.

'Ich sag ja immer: "Wer nicht mit der Zeit geht, der muss halt mir der Zeit gehen ne...!"'

jofenchel Themenstarter:in
117 Beiträge seit 2005
vor 18 Jahren

Hallo zusammen,

ich habe es nochmal probiert.
Mein Laptop ist dann wieder eingefroren.
Ich fahre Xp SP2.
Hatte eigentlich nie Probleme.
Aber ich egal. ich habe meine Tests sehr gut mit einem Timer hinbekommen und weis nun welche Progressbar ich neheme.

Aber nun habe ich ein neues Problem.
Das mit dem Timer hat gut geklappt und ich konnte die Optik und das Aussehen der verschiedenen P-Bars sauber testen.
Nun will ich aber diese P-Bar einsetzten. Und zwar waehrend ich eine etwa 5 MB grosse Datei einlese.
Ich komme aber nicht damit klar wie ich die Fortschrittsanzeige der P-Bar in Bezug zum Fortschitt des Einlesens der Datei bringen soll.
Null Idee. Mit einem Timmer kann ich da wohl nicht arbeiten.
Ich denke das ich vorher die Zeilen der Datei ermitteln sollte und daraus die Prozentzahl errechne. Oder nach der Groesse der Datei?

Eventuell mache ich auch alles zu kompliziert.
Werde heute abend mal testen, falls hier in den USA kein Eishockey kommt 🙂).

JoFenchel

4.221 Beiträge seit 2005
vor 18 Jahren

Kommt darauf an wie Du das File einliest....

Wenn mit this.TextBoxXY.Text=StreamReader.ReadToEnd(); dann wirds schwierig mit Progressbar... dann gehts aber auch so schnell dass es keine Progressbar braucht....

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

jofenchel Themenstarter:in
117 Beiträge seit 2005
vor 18 Jahren

Hallo Programmierhans,

ich lese das File Zeile fuer Zeile ein.
Weil ich jede Zeile mit einem Regex parsen muss.
Deshalb haette ich gerne die P-Bar um den Fortschritt zu sehen.

JoFenchel

4.221 Beiträge seit 2005
vor 18 Jahren

Dann kannst Du ja die Progressbar nach n-Zeilen aktualisieren

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo jofenchel,

eine Fortschrittsanzeige für 5MB? Was sind denn das für aufwändige Regex. Sollte doch eigentlich schwupps gehen. Die Festplatte alleine liest 5MB jedenfalls in Sekundenbruchteilen.

Ansonsten ist doch zeilenweises Einlesen für die Fortschrittsanzeige sehr praktisch, weil du aufs Byte genau wissen kannst, wie weit du schon bist.

Hallo .unreal,

naja, eine Sekunde einfrieren der Anwendung ist doch nicht das gleiche, wie rebooten müssen, weil alles hängt. Außerdem war ja das sekundenweise Blockieren schon ausführlich diskutiert worden.

herbivore

jofenchel Themenstarter:in
117 Beiträge seit 2005
vor 18 Jahren

Hallo herbivore,

Ansonsten ist doch zeilenweises Einlesen für die Fortschrittsanzeige sehr praktisch, weil du aufs Byte genau wissen kannst, wie weit du schon bist.

Sorry, aber ich habe null Ahnung was du meinst oder wie das gehen soll.
Habe schon im Forum gesucht aber nichts gefunden.

JoFenchel

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo jofenchel,

ich denke mal, du meinst Fortschritt in Prozent, oder? Also Summe gelesene Bytes / Filesize * 100 = Fortschritt in %.

Wenn wir mal von Encoding.Default ausgehen, ist ein Zeichen = ein Byte. Die Länge eines String wirst du ermitteln können, oder? Zur Not in der String-Klasse nachgucken. Und die Größe der Datei ist auch nicht schwierig. Zur Not in der FileInfo-Klasse nachgucken.

herbivore

jofenchel Themenstarter:in
117 Beiträge seit 2005
vor 18 Jahren
Kurz davor

Hallo,

ich habe es nun fast zusammen.
Mit FileInfo hole ich mir die Groesse der Datei.

Nur noch eine Frage:

Kann man das eleganter loesen? In weniger Schreibarbeit?


stringlength = lines.Length;
countlines = countlines + stringlength;
Console.WriteLine( countlines );

Danke.

Gruss
JoFenchel

1.549 Beiträge seit 2004
vor 18 Jahren

countlines = countlines +lines.Length;
Console.WriteLine( countlines );

Wir Arbeiten eigendlich nicht wir nehmen nur das geld

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo jofenchel,

von welchem Typ ist lines? String oder String-Array? Ich hoffe mal String, sonst macht das keinen Sinn. Allerdings klingt countlines eher nach String-Array.

Für den String-Fall gilt folgendes:

Wegen der Zeilentrennzeichen, die von ReadLine nicht gelesen werden, müsstest du pro Zeile noch 2 bytes addieren. Außerdem klingt countlines nach Anzahl der Zeilen. Besser wäre vielleicht bytesRead:


bytesRead = bytesRead + lines.Length;
Console.WriteLine (bytesRead);

herbivore

Q
992 Beiträge seit 2005
vor 18 Jahren

countlines += lines.length;
Console.WriteLine( countlines ); 

das könnte auch gehen, wenn du countlines danach nicht mehr brauchst


Console.WriteLine(countlines + lines.length); 

Das ist wohl das kürzeste was geht.

jofenchel Themenstarter:in
117 Beiträge seit 2005
vor 18 Jahren

Hallo,

beide Loesungen von Teichhof und Quallo funktionieren.

Herbivore: lines ist vom typ string. countlines ist vom Typ long.
ICh werde auch in Zukunft mehr sprechende Variablenbezeichner verwenden.
"bytesRead" ist natuerlich besser.
Habe es auch schon geaendert.

Bin gerade noch am tuefteln mit der Prozentanzeige.

Sollte aber keine Schwierigkeit mehr darstellen.

Danke fuer eure Hilfe.

Ich denke wir koennen den Threat schliessen.

JoFenchel

S
14 Beiträge seit 2005
vor 18 Jahren

Halli Hallo,

Ich hab schon wieder mal ne Frage, hoffe, das passt in diesen Thread.

Ich habe eine Funktion in meinem Programm, in welchem ich diverse Kommandos direkt über die Kommandozeile an die Applikation schicken kann.

Eine davon ist sleep.

Das ganze funktioniert folgendermaßen, ich gebe in der Kommandozeile "Progname sleep x" ein, wobei x = anzahl der Millisekunden.

Das GUI friert ein, das ist auch der erwünschte Effekt.
Doch ich möchte, dass die Kommandozeile ebenfalls "schläft".

Ich hab folgenden Code für den Befehl sleep:


 public void doSleep(int iSleep) // Das steht weiter oben
{
    Thread.Sleep(iSleep);
}

// Der Sleep Befehl
case sCmd_Sleep:
     s = "1000";
     if (sArCommand.Length > 1) s = sArCommand[1];
     double d = Conversion.Val(s);
     int i = (int)d;
     if (i < 1) i = 1000;
     doSleep(i);
     break;

Tja, wie gesagt, das GUI friert ein, die Kommandozeile nicht.
In der Hilfe steht leider nur etwas über Thread.Sleep, aber das habe ich ja schon verwendet.
Oder geht das am Ende gar nicht?!
Kann ich mir nicht vorstellen.

Naja, danke schon mal (und danke übrigens für eure letzte Hilfe, kam da nur nicht mehr zum Antworten 😉 )

Gruß,
Suppression

EDIT:

Ich hab mir jetzt überlegt, dass es irgendwie mit einer "process" methode geht.
Zuerst habe ich die "process.start" Methode verwendet:
process.start("cmd.exe", "/k pause x");

Das Problem ist, hier öffnet er ja ne neue Kommandozeile, was natürlich quatsch ist.

Gibt´s vielleicht ne Methode, die den bestehenden Prozess beeinflusst?
Ich will keine Lösung, nur vielleicht die Methode, sollte es sie geben...
Aber keine Angst, ich such schon auch noch selbst 😉

4.221 Beiträge seit 2005
vor 18 Jahren

auf der CommandLine:

Start /Wait Progname sleep 10000

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

S
14 Beiträge seit 2005
vor 18 Jahren

Also erstmal Danke für die Antwort.

Aber leider ist das noch nicht so ganz das was ich Suche, kann man das nicht in den Code mit einbauen, dass es stoppt?

Naja, ich schau morgen noch mal, jetzt bin ich eh schon zuhause...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Suppression,

ich verstehe dein Problem leider nicht ganz. Aber wenn du meinst, dass in der Kommandozeile das Prompt für die nächste Eingabe erst kommen soll, wenn das gestartete Programm wieder beendet wurde, dann muss du das Programm einfach als Konsolenanwendung übersetzen.

herbivore

H
15 Beiträge seit 2008
vor 15 Jahren

Ich habe mal wieder eine Frage, ....

Warum soll Supression seinen Quelltext als Konsolenanwendung Programmieren
Wenn er doch irgendwie eine GUI mit einer Konsole im hintergrund haben will
oder habe ich da was völlig falsch verstanden ?

Gruss Hermann

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Hermann Blobbel,

ich habe nicht gesagt, dass er den Quelltext ändern soll. Das soll er auch nicht. Es geht nur darum, die Anwendung als Konsolenanwendung zu übersetzen, also rein eine Einstellung beim Compilieren. Was der Unterschied ist? Genau was ich geschrieben habe:

Aber wenn du meinst, dass [beim Starten deines Programms] in der Kommandozeile [bzw. genauer: aus der Kommandozeile heraus] das Prompt für die nächste Eingabe erst kommen soll, wenn das gestartete Programm wieder beendet wurde, dann muss du das Programm einfach als Konsolenanwendung übersetzen.

Wenn man das Programm als Windows-Anwendung übersetzt, kommt das das Prompt für die nächste Eingabe sobald die Windows-Anwendung gestartet ist und nicht erst, wenn sie beendet wird.

herbivore

H
15 Beiträge seit 2008
vor 15 Jahren

Surpression schrieb ja weiter oben das wenn er in seine Konsole die neben der
GUI laeuft "sleep" eintippt:
"Das GUI friert ein, das ist auch der erwünschte Effekt.
Doch ich möchte, dass die Kommandozeile ebenfalls "schläft"."

Wenn ich jetzt aber sage im Kompiler ich kompiliere das ganze Programm als Konsolenanwendung. Habe ich dann ueberhaupt noch eine GUI die den gewusnchten effekt erzielen kann ??? Bzw muss ich diese dann nicht erst durch die Konsole starten ?
Das ist das was ich nicht ganz verstehe.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Hermann Blobbel,

kann sein, dass ich die Frage von Suppression falsch verstanden habe. Aber ich schrieb ja auch schon weiter oben:

ich verstehe dein Problem leider nicht ganz.

Ich verstehe ehrlich gesagt auch nicht, warum du das nach drei Jahren aufdröseln willst. Hast du das gleiche Problem wie Suppression? Das scheint mir doch ziemlich spezifisch zu sein. Und Suppression selbst werden wir vermutlich nicht helfen, wenn wir das hier weiter diskutieren. Ich bin daher raus.

herbivore

H
15 Beiträge seit 2008
vor 15 Jahren

Oh, jetzt wo dus sagst, sehe ich auch das das Problem ziemlich alt ist. Ich habe eher wegen dem Sleep problem geschaut und wie du ja weisst habe ich ja urspruenglich nen Vergleich gemacht, zu einem scheinbar aktuelleren Thema, den du ja rausgelöscht hast, weil dieses Thema da geschlossen ist.
Ich wusste nicht das man sich hier nicht auf geschlossene Themen bezehen darf.
Von daher nochmal entschuldigung.

Und auf dieses Thema bin ich eben durch suchen gestossen, habe aber wirklich nicht aufs Datum geachtet.

von daher danke für die Antwort 🙂

gruss Hermann

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Hermann Blobbel,

Ich wusste nicht das man sich hier nicht auf geschlossene Themen bezehen darf.

der Thread, den du meinst, wurde geschlossen, weil die Diskussion in die Irre gelaufen war. Diese Diskussion in einem anderen Thread neu anzufangen/anzufachen, geht dann natürlich nicht. Das wäre ja im Prinzip nichts anderes als einen ganz neuen Thread aufzumachen, auf den bestehenden Thread zu verlinken und das Thema dort weiterzuführen. Beides würde das Schließen des Threads unterlaufen. Und der Thread wurde ja absichtlich geschlossen.

herbivore