Probleme mit timer

15/12/2008 - 23:12 von Patrick Leu | Report spam
Hallo zusammen
Ich habe ien Problem mit dem timer-Steuerelement (VS 2005). Ich habe eine
Schlaufe dir durch das Ergebnis einer DB Abfrage gefüttert wird. In der
Schlaufe sollte eigentlich der timer gestartet werden. Der macht dann einen
auf Stoppuhr. nach Beendigung der Stopuhr soll in der Schlaufe weiter machen
bis diese wieder von vrone beginnt. Das Problem ist nun, dass die Schlaufe
wuneder durchlàuft und erst am Schluss, als wenn die Schlaufe fertig ist
(kein weitere Druchlauf mehr), dann wird der Timer aufgerufen. Was mache ich
falsch? Vielen Dank für Eure Tipps. Gruss, Patrick

private void Timer_Click(object sender, EventArgs e)
{

this.lblZeit.Text = Convert.ToString(std) + ":" +
Convert.ToString(min) +
":" + Convert.ToString(sek);

if (sek == 0 && min > 0)
{
min--;
sek = 59;
}
else if (sek == 0 && min == 0 && std > 0)
{
sek = 59; min = 59;
std--;
}
if (min == 0 && std > 0)
{
min = 59;
std--;
}
if (std == 0 && min == 0 && sek == 0)
{
this.timer1.Stop();
SystemSounds.Question.Play();
MessageBox.Show("Fertig", "Fertig", MessageBoxButtons.OK,
MessageBoxIcon.Asterisk);
}
sek--;
SystemSounds.Beep.Play();
this.pgbTE.Increment(this.pgbTE.Step);

}

private void dlgCountdown_Load(object sender, EventArgs e)
{
string strSQL = "SELECT TPE_TrPrgEinheit.TPE_Bez, * " +
"FROM TPr_TrProgramm INNER JOIN
TPE_TrPrgEinheit ON TPr_TrProgramm.TPr_ID = TPE_TrPrgEinheit.TPr_ID " +
"WHERE (((TPr_TrProgramm.TPr_ID)=" +
strGLBPrgID + ")) " +
"ORDER BY TPE_TrPrgEinheit.TPE_Sequenz;";

CDatenLesen cdrTPr = new CDatenLesen();
IDataReader drTPr = cdrTPr.DatenLesen(strSQL);

while (drTPr.Read())
{
this.lblBez.Text = drTPr["TPE_Bez"].ToString();
this.lblBeschr.Text = drTPr["TPE_Beschr"].ToString();
Zeithacker(drTPr["TPE_Dauer"].ToString());

try
{
timer = Convert.ToDateTime(this.lblZeit.Text);
std = timer.Hour;
min = timer.Minute;
sek = timer.Second;
mil = timer.Millisecond;
// vvvvvvvvvvvvvvv Dieser Timer start erst wenn alles
durch ist
this.timer1.Start(); // < hier sollte eigentlich der
Timer gestartet werden
// ^^^^^^^^^^^^^^^ Dieser Timer start erst wenn alles
durch ist
this.pgbTE.Step = 1; // Progressbar
this.pgbTE.Maximum = (min * 60) + sek + (std * 60 * 60);
this.pgbTE.Minimum = 0;

}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
drTPr.Close();
}
 

Lesen sie die antworten

#1 Elmar Boye
16/12/2008 - 11:07 | Warnen spam
Hallo Patrick,

"Patrick Leu" schrieb ...

Ich habe ien Problem mit dem timer-Steuerelement (VS 2005).



Und ich habe so das eine oder andere Problem mit Deinem Code,
da geht der Timer ja regelrecht unter ;-)

Ich habe eine Schlaufe dir durch das Ergebnis einer DB Abfrage gefüttert wird.
In der Schlaufe sollte eigentlich der timer gestartet werden.
Der macht dann einen auf Stoppuhr.
nach Beendigung der Stopuhr soll in der Schlaufe weiter machen
bis diese wieder von vrone beginnt. Das Problem ist nun, dass die Schlaufe
wuneder durchlàuft und erst am Schluss, als wenn die Schlaufe fertig ist
(kein weitere Druchlauf mehr), dann wird der Timer aufgerufen.



Auch mit größeren Anstrengungen habe ich das aus dem Code
nicht herauslesen können.

Was mache ich falsch?



Mein Rat. Ràume zunàchst einmal auf.
Wenn Du die folgende _gutgemeinte_ Kritik ernstnimmst,
fàngst Du am besten ganz von vorne an.


private void Timer_Click(object sender, EventArgs e)
{

this.lblZeit.Text = Convert.ToString(std) + ":" + Convert.ToString(min) +
":" + Convert.ToString(sek);



Die Anzeige direkt über die eingebaute Formatierung erfolgen.


if (sek == 0 && min > 0)



Die diversen Zeitvariablen können durch ein DateTime ersetzt werden.
Die Rechenoperationen wàren ein einfaches AddSeconds(-1).
Wobei die ganze Rechnerei bei einem 1 sekündigen Timer auch
entfallen können.

if (std == 0 && min == 0 && sek == 0)



Der Vergleich kann mit der ursprünglichen Startzeit erfolgen.
Wobei man niemals davon ausgehen sollte, dass ein Timer zu
exakten Zeiten ausgelöst wird, ein Vergleich auf größer oder
gleich ist zu empfehlen. Siehe Beschreibung zu Timer:
http://msdn.microsoft.com/de-de/lib...timer.aspx


{
this.timer1.Stop();
SystemSounds.Question.Play();
MessageBox.Show("Fertig", "Fertig", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);



Bei der jetztigen Konstruktion wird die Leseschleife bis zum OK angehalten.

}
sek--;

SystemSounds.Beep.Play();
this.pgbTE.Increment(this.pgbTE.Step);

}

private void dlgCountdown_Load(object sender, EventArgs e)
{
string strSQL = "SELECT TPE_TrPrgEinheit.TPE_Bez, * " +
"FROM TPr_TrProgramm INNER JOIN
TPE_TrPrgEinheit ON TPr_TrProgramm.TPr_ID = TPE_TrPrgEinheit.TPr_ID " +
"WHERE (((TPr_TrProgramm.TPr_ID)=" +
strGLBPrgID + ")) " +
"ORDER BY TPE_TrPrgEinheit.TPE_Sequenz;";



Als Exkurs mehr die Kategorie SQL: Verwende hier besser ein
Command-Objekt mit einem Parameter.

CDatenLesen cdrTPr = new CDatenLesen();
IDataReader drTPr = cdrTPr.DatenLesen(strSQL);



Das sollten zwei ein Using Blöck werden, denn Verbindungen können
auch mal abbrechen, DataReader fehlerhafte Daten liefern uam.

Und die unten stehende Exception MessageBox sollte aussen rum stehen,
damit die Resssourcen nicht bis OK hàngen.


while (drTPr.Read())
{
this.lblBez.Text = drTPr["TPE_Bez"].ToString();
this.lblBeschr.Text = drTPr["TPE_Beschr"].ToString();
Zeithacker(drTPr["TPE_Dauer"].ToString());

try
{
timer = Convert.ToDateTime(this.lblZeit.Text);



Zurück zum Problem: Wo kommt hier die erste Zeit weg?
Wobei man den Startwert weniger aus einem Label gewinnen sollte,
sondern als direkte Variable.

std = timer.Hour;
min = timer.Minute;
sek = timer.Second;
mil = timer.Millisecond;



Das Zerlegen sollte man sich hier sparen (siehe oben).

// vvvvvvvvvvvvvvv Dieser Timer start erst wenn alles durch ist
this.timer1.Start(); // < hier sollte eigentlich der Timer gestartet werden
// ^^^^^^^^^^^^^^^ Dieser Timer start erst wenn alles durch ist



Genau das Starten tut er nicht am Ende, sondern mittendrin...
Er làuft ab hier als unabhàngig wàhrend Du in der Schleife immer weiter liest.
Das obige Timer_Click je nach dem eingestellten Interval (was steht da?) ausgelöst.

this.pgbTE.Step = 1; // Progressbar
this.pgbTE.Maximum = (min * 60) + sek + (std * 60 * 60);
this.pgbTE.Minimum = 0;




Und die Progressbar? wird jeweils neu initialisiert.
Der gesamte Codeteil sollte vor das while (drTPr.Read()).
In der Schleife sollte ein Application.DoEvents kommen,
damit der Timer zum Zuge kommt.

}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}



Die "Fehlerbehandlung" gehört nach ganz aussen, denn die
sind eher bei den Datenbankoperationen zu erwarten.
So behandelst Du am wahrscheinlichsten einen Fehler bei der Konvertierung
des Label-Inhaltes (und das sollte erst gar nicht passieren -> DateTime Variable).

}
drTPr.Close();



Und die vermutete Verbindung (aus CDatenLesen) gehört auch geschlossen.

}




Gruß Elmar

Ähnliche fragen