Avatar billede mettegp Nybegynder
07. januar 2006 - 11:51 Der er 17 kommentarer

sammenligning af tidspunkter - datetime - problematik

Jeg har lavet et lille server - klient program - Bruuns Auktionshus. En klient kan via en GUI indtaste et bud. Samtidigt generes der et budtidspunkt som sendes til serveren. Det virker fint. Men når budtidspunktet skal sammenlignes med et tidstempel genereret med et sekunds mellemrum, sat af serveren inde i den anden while lykke i min HaandterKunde() metode sker der ligesom ikke noget.
Det er meningen at hvis en kunde byder inden der er gået 10 sekunder skriver serveren "ingen højere" og det skal så være muligt for en ny kunde at byde. Det skal så være den nye tid der sammenlignes. Så langt så godt.
Men hvis der er gået 10 sekunder uden der på ny er budt, skal serveren skrive til kunden/erne beskeden "første". Hvis der er gået yderligere 5 sekunder skal der skrives "anden" og hvis der er gået yderligere 3 sekunder skal der skrives "tredie, varen er solgt!". Men det gør den ikke.
Det er ligesom sammenligningen aldrig bliver foretaget, kommer ikke ind i if-sætningerne i den anden while lykke.

Autionshusvarer er et singleton objekt.

Er der nogen der kan fortælle mig hvad jeg gør galt?


       
public void HaandterKunde()
{
double budFraKunde;
string serverBesked;
DateTime budTidspunkt;

NetworkStream networkStream = new NetworkStream(this.kunde);
StreamReader streamReader = new StreamReader(networkStream);
StreamWriter streamWriter = new StreamWriter(networkStream);

string kundeIPadresse = ((IPEndPoint)this.kunde.RemoteEndPoint).Address.ToString();
           
//tilfoej streamwriter til monitor
monitor.AddStreamWriter(streamWriter);

//send velkomst til kunde
serverBesked = "\rVelkommen til Bruuns Auktionshus! \rVare på auktion er: "+this.GetVare().ToString()+"\rGiv bud";

monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
           
while(true)        //sålænge der kommunikeres med kunde 
{
try
{
//server læser bud og budtidspunkt fra kunde
budFraKunde = Convert.ToDouble(streamReader.ReadLine());
budTidspunkt = Convert.ToDateTime(streamReader.ReadLine());
   
monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);
}
catch(IOException)
{
break;
}
       
//sammenlign bud fra kunde med varen på auktions aktuelle hoejeste bud

if(budFraKunde <= Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetHoejesteBud())
{
//broadcast serverbesked til de andre kunder
serverBesked = "Budet på "+budFraKunde+" kr. er for lavt! "+budTidspunkt+" Giv nyt bud";

monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
continue;
}

//budet skal kun sættes hvis det er højere end startbudet, så det gælder som den nye mindstepris               
Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().SetHoejesteBud(budFraKunde);
Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().SetBudTidspunkt(budTidspunkt);
               
string hammerslag;
               
budTidspunkt = Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetBudTidspunkt();
               
int counter = 0;
while(true)
{
   
//tidstempel sat af serveren, bruges til sammenligning

DateTime tidstempel = DateTime.Now;
Thread.Sleep(1000);
       
TimeSpan tiSekunder = new TimeSpan(0,0,10);
tidstempel = tidstempel.Subtract(tiSekunder);

if(budTidspunkt > tidstempel)
{   
//udskrive det nye bud
monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);

serverBesked = "Ingen højere?";
monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
}   
   
//her er mit problem, den kommer ligesom aldrig ind og foretager sammenligningen
//så er der gået 10 sekunder uden nogen har budt
if(budTidspunkt.Equals(tidstempel))
{
hammerslag = "første";
monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
}
       
TimeSpan femtenSekunder = new TimeSpan(0,0,15);
tidstempel = tidstempel.Subtract(femtenSekunder);
if(budTidspunkt == tidstempel)
{
hammerslag = "anden";
monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
}

TimeSpan attenSekunder = new TimeSpan(0,0,18);
tidstempel = tidstempel.Subtract(attenSekunder);
if(budTidspunkt == tidstempel)
{
hammerslag = "tredie, varen er solgt!";
monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
int vareNr = Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetVareNr();
Auktionsvarer.GetAuktionsvarer().RemoveEnVare(vareNr);
break;
}
                   
//give mulighed for at ny kunde kan give et bud
budFraKunde = Convert.ToDouble(streamReader.ReadLine());
budTidspunkt = Convert.ToDateTime(streamReader.ReadLine());

counter++;
}//end indre while løkke (hammerslag)}//end ydre while løkke

}//end ydre while løkke

//fjern streamwriter fra monitor
monitor.RemoveStreamWriter(streamWriter);

Console.WriteLine("Forbindelse til kunde lukkes ned...\n");
streamWriter.Close();
streamReader.Close();
networkStream.Close();
}
Avatar billede sovsekoder Nybegynder
07. januar 2006 - 12:17 #1
hvis jeg var dig ville jeg nok gribe debuggeren:

// INDSÆT DENNE LINIE
Console.WriteLine("her1 budTidspunkt = "+budTidspunkt+", tidstempel = "+tidstempel);
//her er mit problem, den kommer ligesom aldrig ind og foretager sammenligningen
//så er der gået 10 sekunder uden nogen har budt
if(budTidspunkt.Equals(tidstempel))
{
Console.WriteLine("her2");
hammerslag = "første";
monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
}
Console.WriteLine("her3");
Avatar billede sovsekoder Nybegynder
07. januar 2006 - 12:19 #2
bruge visual studios "output" vindue til at se hvad der præcis sker...
der er vel 2 muligeder :
1) fejlen ligger i koden ovenover (måske hænger den eller exit i koden - exceptions!?)
2) fejlen ligger i sammenligningen: if(budTidspunkt.Equals(tidstempel))
Avatar billede sovsekoder Nybegynder
07. januar 2006 - 12:29 #3
hov?! det ser lidt mystisk ud... din sammen ligning er noget med "equals" eller "=" hvilket betyder at dine tidspunkter skal være HELT præcis ens (ned til millisekunder) - vil dette være tilfældet?

...ved ikke lige hvordan din kode hænger sammen, men jeg kunne forestille mig at at du skulle lave noget med <= eller >= i din sammenligning for at undgå at de skal matche værdien på millisekundspræcis. :o ?!?!?
Avatar billede sovsekoder Nybegynder
07. januar 2006 - 12:29 #4
håber at mine kommentarer kan hjælpe dig lidt på vej...
Avatar billede nielle Nybegynder
07. januar 2006 - 13:06 #5
Du aflæser et tidspunkt som sendes til server fra klienten. Med den metode er du afhængig af af klienternes og serverens ure går ens. Dette er en meget risikabel antagelse - i stedet bør du udelukkende arbejde med server-tid.
Avatar billede nielle Nybegynder
07. januar 2006 - 13:09 #6
... og burde:

tidstempel = tidstempel.Subtract(tiSekunder)

- ikke have været:

tidstempel = tidstempel.Add(tiSekunder)
Avatar billede mettegp Nybegynder
07. januar 2006 - 14:36 #7
hej sovsekoder og nielle
tak for jeres hjælp.
Nu har jeg lavet budtidspunktet om til en servertid. denne tid sættes på varen. jeg forestiller mig at den så står stille. Inde i den anden while løkke sættes et andet tistempel der skal bruges til sammenligning. Dette tidstempel forestiller jeg mig genereres med et sekunds mellemrum.
Det jeg gerne vil kode er:
if(budTidspunkt > tidstempel - 10 sekunder)
f.eks. hvis budTidspunktet er 10.16.32 > 10.16.40 - 10 sekunder)
så er tidspunkterne ikke ens og der er ikke gået 10. dvs. en ny klient kan have budt og det er hans tid der bruges indtil en ny klient byder osv.
Det er først når
tidstemple er nået op på 10.16.32 == 10.16.42 - 10 sekunder at tiderne er ens, dvs. der er gået 10 sekunder uden nogen har budt også er det den skal skrive "første"
men det gør den ikke.
Men det kan godt være det ikke udtrykkes rigtigt med tidstempel = tidstempel.subtract(tiSekunder). tidstemplet skal vokse med et sekund hele tiden og budtidspunktet skal stå stille.
Jeg har prøvet at debugge og sætte console.Writeline() ind, men den kommer bare ikke ind i if-sætningen. Jeg håber ikke jeg lyder alt for tosset men jeg er lidt ny mht. til at kode.
Avatar billede mettegp Nybegynder
07. januar 2006 - 14:40 #8
Jeg har sendt det som en kommentar, skulle jeg have sendt det som et svar
Avatar billede nielle Nybegynder
07. januar 2006 - 16:59 #9
Nej, du skal ikke lægge den som et svar. Eksperten bruger "svar" til at kunne give point til dem som spørgeren synes skal have point. Det bruges ikke til når man svare på hinandens spørgsmål. :^)

Prøv at vise os den seneste version af koden - den er vel lavet en del om nu i forhold til det ovenstående.
Avatar billede mettegp Nybegynder
07. januar 2006 - 18:58 #10
Nu ser koden sådan her ud. Efter at jeg sammenligner tiderne på seconds kunne jeg godt bruge equals eller ==. Det virkede også da jeg kun kørte en kunde igennem. Men når jeg giver mulighed for at køre flere kunder igennem, det kan jeg kun hvis jeg gentager indlæsning af budFraKunde og budTidspunkt inde i den 2'den while løkke så opfører den sig ikke helt efter reglerne. Den springer f.eks. beskeden "første" over og uret går ikke på serveren hvis jeg ikke har givet bud fra 2 til 3 kunder. Uret skulle jo gerne starte med den første kunde der giver et bud. Men den står bare og bliker på consollen. Jeg ved ikke rigtig hvad jeg gør galt???

//trådmetode som modtager bud fra en klient og sender budet videre til alle de
//andre kunder
       
public void HaandterKunde()
{
double budFraKunde;
string serverBesked;
DateTime budTidspunkt;

NetworkStream networkStream = new NetworkStream(this.kunde);
StreamReader streamReader = new StreamReader(networkStream);
StreamWriter streamWriter = new StreamWriter(networkStream);

string kundeIPadresse = ((IPEndPoint)this.kunde.RemoteEndPoint).Address.ToString();
           
//tilfoej streamwriter til monitor
monitor.AddStreamWriter(streamWriter);

//send velkomst til kunde
serverBesked = "\rVelkommen til Bruuns Auktionshus! \rVare på auktion er: "+this.GetVare().ToString()+"\rGiv bud";
monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
           
while(true)        //sålænge der kommunikeres med kunde 
{
try
{
//server læser bud fra kunde
budFraKunde = Convert.ToDouble(streamReader.ReadLine());
budTidspunkt = DateTime.Now;        //budtidspunkt er nu sat på serversiden
monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);
}
catch(IOException)
{
break;
}
               
//sammenlign bud fra kunde med varen på auktions aktuelle hoejeste bud
if(budFraKunde <= Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetHoejesteBud())
{
//broadcast serverbesked til de andre kunder
serverBesked = "Budet på "+budFraKunde+" kr. er for lavt! "+budTidspunkt+" Giv nyt bud";
monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
continue;
}

//budet skal kun sættes hvis det er højere end startbudet, så det gælder som den nye mindstepris               
Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().SetHoejesteBud(budFraKunde);
Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().SetBudTidspunkt(budTidspunkt);
   
budTidspunkt = Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetBudTidspunkt();
               
string hammerslag;
int counter = 0;

while(true)
{   
    DateTime tidstempel = DateTime.Now;
    Thread.Sleep(1000);
   
    Console.WriteLine("Budtidspunkt "+budTidspunkt);
    Console.WriteLine("servertid "+tidstempel);
    TimeSpan tiSekunder = new TimeSpan(0,0,10);
    tidstempel = tidstempel.Subtract(tiSekunder);
               
    if(budTidspunkt.Second > tidstempel.Second)
    {   
    Console.WriteLine("tidstempel 0 "+tidstempel);
    serverBesked = "Ingen højere?";
    Console.WriteLine("Ingen højere?");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);

        //problem her
    //give mulighed for at ny kunde kan give et bud
    budFraKunde = Convert.ToDouble(streamReader.ReadLine());
    budTidspunkt = Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetBudTidspunkt();

    //udskrive det nye bud
    monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);
    continue;
        }   
   
    //så er der gået 10 sekunder uden nogen har budt
    if(budTidspunkt.Second == tidstempel.Second)
    {
    Console.WriteLine("tidstempel 1 "+ tidstempel);
    hammerslag = "første";
    Console.WriteLine("første");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    continue;
    }
       
    TimeSpan femtenSekunder = new TimeSpan(0,0,15);
    tidstempel = tidstempel.Subtract(femtenSekunder);
    if(budTidspunkt.Second == tidstempel.Second)
    {
    Console.WriteLine("tidstempel 2 "+ tidstempel);
    hammerslag = "anden";
    Console.WriteLine("anden");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    continue;
    }
    TimeSpan attenSekunder = new TimeSpan(0,0,18);
    tidstempel = tidstempel.Subtract(attenSekunder);
    if( budTidspunkt.Second == tidstempel.Second)
    {
    Console.WriteLine("tidstempel 3 "+tidstempel);
    Console.WriteLine("tredie, varen er solgt!");
    hammerslag = "tredie, varen er solgt!";
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    break;
    }

counter++;
}//end indre while løkke (hammerslag)
   
}//end ydre while løkke

//fjern streamwriter fra monitor
monitor.RemoveStreamWriter(streamWriter);
Console.WriteLine("Forbindelse til kunde lukkes ned...\n");
streamWriter.Close();
streamReader.Close();
networkStream.Close();
}
Avatar billede mettegp Nybegynder
07. januar 2006 - 21:34 #11
Nu har jeg flyttet indlæsningen fra den første if-sætning til slutningen af løkken.

//give mulighed for at ny kunde kan give et bud
budFraKunde = Convert.ToDouble(streamReader.ReadLine());
budTidspunkt = Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetBudTidspunkt();
   
//udskrive det nye bud
monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);

Nu skriver den "første" men ikke "anden" og "tredie, varen er solgt", tæller op en gang og står så og blinker. Jeg ved ikke hvorfor den ikke fortsætter med at tælle op så den kan foretage de andre sammenligninger, som den gør hvis jeg ikke gentager indlæsningen???
               



int counter = 0;
while(true)
{   
DateTime tidstempel = DateTime.Now;
Thread.Sleep(1000);
                   
Console.WriteLine("Budtidspunkt "+budTidspunkt);
Console.WriteLine("tidstempel "+tidstempel);

TimeSpan tiSekunder = new TimeSpan(0,0,10);
tidstempel = tidstempel.Subtract(tiSekunder);
                   
if(budTidspunkt.Second > tidstempel.Second)
{   
        Console.WriteLine("tidstempel 0 "+tidstempel);
        serverBesked = "Ingen højere?";
    Console.WriteLine("Ingen højere?");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
    continue;
}   
   
//så er der gået 10 sekunder uden nogen har budt
if(budTidspunkt.Second == tidstempel.Second)
{
    Console.WriteLine("tidstempel 1 "+ tidstempel);
    hammerslag = "første";
    Console.WriteLine("første");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    continue;
}
                   
TimeSpan femtenSekunder = new TimeSpan(0,0,15);
tidstempel = tidstempel.Subtract(femtenSekunder);
if(budTidspunkt.Second == tidstempel.Second)
{
    Console.WriteLine("tidstempel 2 "+ tidstempel);
    hammerslag = "anden";
    Console.WriteLine("anden");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    continue;
}

TimeSpan attenSekunder = new TimeSpan(0,0,18);
tidstempel = tidstempel.Subtract(attenSekunder);
if( budTidspunkt.Second == tidstempel.Second)
{
    Console.WriteLine("tidstempel 3 "+tidstempel);
    Console.WriteLine("tredie, varen er solgt!");
    hammerslag = "tredie, varen er solgt!";
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    break;
}

//flyttet
//give mulighed for at ny kunde kan give et bud
budFraKunde = Convert.ToDouble(streamReader.ReadLine());
budTidspunkt = Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetBudTidspunkt();
                   
//udskrive det nye bud
monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);

counter++;
}//end indre while løkke (hammerslag)
Avatar billede nielle Nybegynder
07. januar 2006 - 21:58 #12
Hvad med noget i denne stil?

                int counter = 0;
                while (true)
                {
                    Thread.Sleep(1000);
                    DateTime nu = DateTime.Now;

                    Console.WriteLine("Budtidspunkt " + budTidspunkt);
                    Console.WriteLine("tidstempel " + nu);

                    if (budTidspunktAddSeconds(18) >= nu)
                    {
                        Console.WriteLine("tidstempel 3 " + nu);
                        Console.WriteLine("tredie, varen er solgt!");
                        hammerslag = "tredie, varen er solgt!";
                        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
                    }
                    else if (budTidspunktAddSeconds(15) >= nu)
                    {
                        Console.WriteLine("tidstempel 2 " + nu);
                        hammerslag = "anden";
                        Console.WriteLine("anden");
                        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
                    }
                    else if (budTidspunktAddSeconds(10) >= nu)
                    {
                        Console.WriteLine("tidstempel 1 " + nu);
                        hammerslag = "første";
                        Console.WriteLine("første");
                        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
                    }
                    else
                    {
                        Console.WriteLine("tidstempel 0 " + nu);
                        serverBesked = "Ingen højere?";
                        Console.WriteLine("Ingen højere?");
                        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
                    }

                    //udskrive det nye bud
                    monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);

                    counter++;
                }//end indre while løkke (hammerslag)

            }//end ydre while løkke
Avatar billede mettegp Nybegynder
07. januar 2006 - 23:50 #13
hej nielle
det er virkelig morsomt.
Hvis jeg skrev som du sagde
if(buTidspunkt.AddSeconds(18) >= nu)osv,
så skrev den varen er solgt med det samme, så når den slet ikke at tælle, og giver ikke mulighed for indtastning af nye bud.
Så jeg vendte dem om, så der står
if(buTidspunkt.AddSeconds(18) <= nu)osv
Nu får jeg lov til at indtaste nye bud, men den skriver ingen højere 10 gange og første 5 gange og anden 3 gange før den tilsidst skriver tredie, varen er solgt og hopper ud af løkken. Og den løber hele baduljen igennem for hver nyt bud der bliver indtastet. Men det er det bedste resultat indtil videre, så nu stopper jeg for idag. Er træt. Men tusind tak for hjælpen.
Jeg tror måske det ville være nemmere hvis man havde en timer, som genstartede med at tælle hver gang et nyt bud blev givet. Men jeg har slet ikke prøvet at arbejde med timere.
Avatar billede nielle Nybegynder
08. januar 2006 - 09:00 #14
Hmm, jeg kan nu ikke se hvorfor at det skulle give et mere rigtigt resultat at vende >= til <=. Det er ikke en logisk opførelse (og det er også derfor at du får hammerslagene ud i den forkerte rækkefølge). Mht. det at hammerslagene bliver gentaget, så kan det klares med dette:

                string hammerslag;
                int counter = 0;
                while (true)
                {
                    Thread.Sleep(1000);
                    DateTime nu = DateTime.Now;

                    Console.WriteLine("Budtidspunkt " + budTidspunkt);
                    Console.WriteLine("tidstempel " + nu);

                    if (budTidspunkt.AddSeconds(18) >= nu && hammerslag != "tredie, varen er solgt!")
                    {
                        Console.WriteLine("tidstempel 3 " + nu);
                        hammerslag = "tredie, varen er solgt!";
                        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
                    }
                    else if (budTidspunkt.AddSeconds(15) >= nu && hammerslag != "anden")
                    {
                        Console.WriteLine("tidstempel 2 " + nu);
                        hammerslag = "anden";
                        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
                    }
                    else if (budTidspunkt.AddSeconds(10) >= nu && hammerslag != "første")
                    {
                        Console.WriteLine("tidstempel 1 " + nu);
                        hammerslag = "første";
                        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
                    }
                    else if (hammerslag != "Ingen højere?")
                    {
                        Console.WriteLine("tidstempel 0 " + nu);
                        hammerslag = "Ingen højere?";
                        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
                    }

                    Console.WriteLine(hammerslag);

                    //udskrive det nye bud
                    monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);

                    counter++;
                }//end indre while løkke (hammerslag)
Avatar billede mettegp Nybegynder
08. januar 2006 - 15:15 #15
Nu har jeg gjordt nøjagtig som du anviser. Resultatet jeg får ud af det på consollen er:

GUI
127.0.0.1(1):
Velkommen til Bruuns Auktionshus!
Vare på auktion er:

Varenr.: 101
Betegnelse: Antikt skrivepult fra 1805
Hoejeste bud: 5000
Bud tidspunkt: 08-01-2006 14:45:43
Giv bud
127.0.0.1(1): 6000 08-01-2006 14:45:47
127.0.0.1(1): tredie, varen er solgt!

Consol
start budtidspunkt 14:06:19
start nu 14:06:19

budtidspunkt 3 14:06:19
nu 3 14:06:19
tredie, varen er solgt!

                           
Der går 1 sekund, så skriver den tredie, varen er solgt!
Dvs. nu når ikke at tælle op til 10, 15 eller atten, og skrive de korrekte beskeder til klienten. Inden jeg tilføjede hammerslag i if sætningerne havde jeg en else på den første if-sætning. Dvs. det der foregår i else er modsat det der foregår i if
så hvis if(budTidspunkt.AddSeconds(18) >= nu, så må else være budTidspunkt.AddSeconds(18) < nu, og denne situation forekommer aldrig fordi budTidspunkt og nu har samme start værdi. hvorefter nu vokser med 1 for hvert sekund, Så derfor skriver den med det samme tredie, varen er solgt!. Den kommer aldrig ned i else sætningen og skriver beskeden "Ingen højere!". Sådan forstår jeg det ihvertfald, eller er jeg hel gal på den.
Så prøvede jeg at vende tegnene om og nu har jeg tilføjet hammerslag til if-sætningerne for at fjerne gentagelser. Nedenfor ses resultatet jeg fik i min GUI med 2 indtastninger af bud på hhv. 6000 og 7000 med 3-4 sekunders mellemrum. Jeg kan godt se at denne løsning ikke er god, fordi varen sælges selvom der kommer et nyt bud, inden der er nået at gå 10 18 sekunder. Den løber hele den indre while løkke (hammerslag) igennem for hvert bud. Og det skal den jo ikke den skal stoppe, når der kommer et nyt bud også starte forfra med at tælle op til første, anden og tredie.
Jeg håber dette bedre forklarer problemet.
Det er en rigtig god øvelse vi har fået for man bliver tvunget til at tænke, men jeg synes den er svær.

GUI
127.0.0.1(1):
Velkommen til Bruuns Auktionshus!
Vare på auktion er:

Varenr.: 101
Betegnelse: Antikt skrivepult fra 1805
Hoejeste bud: 5000
Bud tidspunkt: 08-01-2006 14:37:26
Giv bud
127.0.0.1(1): 6000 08-01-2006 14:37:30
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): første!
127.0.0.1(1): 6000 08-01-2006 14:37:30
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): anden!
127.0.0.1(1): 6000 08-01-2006 14:37:30
127.0.0.1(1): første!
127.0.0.1(1): 6000 08-01-2006 14:37:30
127.0.0.1(1): anden!
127.0.0.1(1): 6000 08-01-2006 14:37:30
127.0.0.1(1): tredie, varen er solgt!
127.0.0.1(1): 7000 08-01-2006 14:37:49
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): første!
127.0.0.1(1): 7000 08-01-2006 14:37:49
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): Ingen højere?
127.0.0.1(1): anden!
127.0.0.1(1): 7000 08-01-2006 14:37:49
127.0.0.1(1): første!
127.0.0.1(1): 7000 08-01-2006 14:37:49
127.0.0.1(1): anden!
127.0.0.1(1): 7000 08-01-2006 14:37:49
127.0.0.1(1): tredie, varen er solgt!

int counter = 0;
while(true)
{   
    DateTime nu = DateTime.Now;
    Thread.Sleep(1000);

    Console.WriteLine("start Budtidspunkt "+budTidspunkt);
    Console.WriteLine("start nu "+nu);
   
//      if(budTidspunkt >= nu.Subtract(TimeSpan.FromSeconds(18)))
    if(budTidspunkt.AddSeconds(18) >= nu && hammerslag != "tredie, varen er solgt!")
    {
    Console.WriteLine("budtidspunkt 3 "+budTidspunkt);
    Console.WriteLine("nu 3 "+nu);
    Console.WriteLine("tredie, varen er solgt!");
    hammerslag = "tredie, varen er solgt!";
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    break;
    }
//    else if(budTidspunkt >= nu.Subtract(TimeSpan.FromSeconds(15)))
    else if(budTidspunkt.AddSeconds(15) >= nu && hammerslag != "anden!")
    {
    Console.WriteLine("budtidspunkt 2 "+budTidspunkt);
    Console.WriteLine("nu 2 "+ nu);
    hammerslag = "anden!";
    Console.WriteLine("anden!");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    continue;
    }
//    else if(budTidspunkt >= nu.Subtract(TimeSpan.FromSeconds(10)))            else if(budTidspunkt.AddSeconds(10) >= nu && hammerslag != "første!")
    {   
    Console.WriteLine("budtidspunkt 1 "+budTidspunkt);
    Console.WriteLine("nu 1 "+ nu);
    hammerslag = "første!";
    Console.WriteLine("første!");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);   
    continue;
    }   
    else if(hammerslag != "Ingen højere?")
    {
    Console.WriteLine("budtidspunkt 0 "+budTidspunkt);
    Console.WriteLine("nu 0 "+nu);
    serverBesked = "Ingen højere?";
    Console.WriteLine("Ingen højere?");
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
    continue;
    }

//    give mulighed for at ny kunde kan give et bud
//    budFraKunde = Convert.ToDouble(streamReader.ReadLine());
//    budTidspunkt = Auktionsvarer.GetAuktionsvarer().VarePaaAuktion().GetBudTidspunkt();

//    udskrive det nye bud
    monitor.BroadcastAuktionsBud(kundeIPadresse, budFraKunde, budTidspunkt);
    counter++;

}//end indre while løkke (hammerslag)
Avatar billede nielle Nybegynder
08. januar 2006 - 22:10 #16
Det du viser ner nu ikke 100% den kode som jeg har postet. I hvert fald er der en forskel hvor du har:

serverBesked = "Ingen højere?";

- mens jeg har:

hammerslag = "Ingen højere?";

Dette er grunden til at du har så mange linjer med "Ingen højere?" Jeg kan se mange flere afvigelser end det, så det er nu lidt misvisende når du skriver at du har "gjordt nøjagtig som du anviser". :^|

Nå, men videre til algoritmen...

Variablen budtidspunkt skulle gerne indeholde tidspunktet for det sidste bud - enten af den specifikke kunde eller af en af de andre som byder i samme auktion. Variaben nu skulle gerne indeholde ”klokken lige nu”.

1) Hvis ”nu” ligger 18 sekunder, eller mere, efter ”budtidspunkt” er hammerslaget lig ”tredie, varen er solgt!”. Dette skal skrives én gang.

Hvis 1) ikke er opfyldt, må ”nu” ligge mindre end 18 sekunder efter ”budtidspunkt”:

2) Hvis ”nu” ligger 15 sekunder, eller mere, efter ”budtidspunkt ” er hammerslaget ”anden”. Dette skal skrives én gang.

Hvis 2) heller ikke er opfyldt, må ”nu” ligge mindre end 15 sekunder efter ”budtidspunkt”:

3) Hvis ”nu” ligger 10 sekunder, eller mere, efter ”budtidspunkt ” er hammerslaget ”første”. Dette skal skrives én gang.

Hvis 3) heller ikke er opfyldt, må ”nu” ligge mindre end 10 sekunder efter ”budtidspunkt”:

4) Men så er hammerslaget ”Ingen højere?"”. Dette skal skrives én gang.

Dette er lige præcis det som denne algoritme burde gøre:

DateTime nu = DateTime.Now;

Console.WriteLine("Budtidspunkt " + budTidspunkt);
Console.WriteLine("tidstempel " + nu);

if (budTidspunkt.AddSeconds(18) >= nu)
{
    if (hammerslag != "tredie, varen er solgt!")
    {
        Console.WriteLine("tidstempel 3 " + nu);
        hammerslag = "tredie, varen er solgt!";
        Console.WriteLine(hammerslag);
        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    }
}
else if (budTidspunkt.AddSeconds(15) >= nu)
{
    if (hammerslag != "anden")
    {
        Console.WriteLine("tidstempel 2 " + nu);
        hammerslag = "anden";
        Console.WriteLine(hammerslag);
        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    }
}
else if (budTidspunkt.AddSeconds(10) >= nu)
{
    if (hammerslag != "første")
    {
        Console.WriteLine("tidstempel 1 " + nu);
        hammerslag = "første";
        Console.WriteLine(hammerslag);
        monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    }
}
else if (hammerslag != "Ingen højere?")
{
    Console.WriteLine("tidstempel 0 " + nu);
    hammerslag = "Ingen højere?";
    Console.WriteLine(hammerslag);
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
}
Avatar billede mettegp Nybegynder
09. januar 2006 - 19:07 #17
Hej nielle,

jeg sender dig de væsentligste kodebrokker fra mit program. Jeg har lavet en Bud klasse som har en pris og et budtidspunkt samt en auktionsbyder. Så har jeg lavet en Byd metode som sammenligner det indkomne bud med det højeste og returnerer en serverbesked til kunden. På denne måde får jeg sat mit bud og budtidspunkt på den aktuelle auktionsvare. Hvis det aktuelle højeste bud er mindre end det indkomne bud så sættes det nye bud som det højeste og beskeden "ingen højere" sendes til kunden. Og ellers får kunden besked på at indtaste et nyt bud, fordi det er for lavt. Derfor har jeg fjernet else if sætningen hvor if(Hammerslag Ingen højere) blev sammenlignet i den anden while løkke fra tidligere. Så det kun er hammerslag der sammenlignes. Og ellers bruger jeg din logaritme.

Det resultat jeg får er

127.0.0.1(1):
Velkommen til Bruuns Auktionshus!
Vare på auktion er:

Varenr.: 100
Betegnelse: Antik skrivepult fra 1805
Start pris: 5000
Giv bud
127.0.0.1(1): 6000 09-01-2006 18:39:48
127.0.0.1(1): Ingen højere!
127.0.0.1(1): tredie, varen er solgt!

på consollen står der
startBudtidspunkt 18:39:48
start nu 18:39:48

budTidspunkt 3 18:40:06    //Men der er ikke gået 18 sekunder???
nu 3 18:39:48
tredie, varen er solgt!

skriver den ikke beskeden med det samme, fordi budTidspunktet er større end det første nu tidspunkt den sammenligner med?
Den når ikke at tælle til hverken 18, 15, eller 10 og skrive de passende beskeder til kunden, førend den skriver "tredie, varen er solgt!" eller give mulighed for at indtaste et nyt bud. Hvad gør jeg forkert???

skal jeg ikke også på en eller anden måde bryde den anden while løkke, hvis et nyt bud gives?



public class Bud
{
private Auktionskunde auktionsbyder;    //associering til auktionskunde objekt
private double pris;
private DateTime budTidspunkt;

public Bud(Auktionskunde auktionsbyder, double pris, DateTime budTidspunkt)
{
        this.auktionsbyder = auktionsbyder;
    this.pris = pris;

    //budTidspunktet sættes når der oprettes et bud
    this.budTidspunkt = budTidspunkt;   
}

//Get-metoder
public DateTime GetBudTidspunkt(){return this.budTidspunkt;}
public double GetPris(){return this.pris;}
//Get-metode til associeret Auktionskunde objekt
public Auktionskunde GetAuktionskunde(){return this.auktionsbyder;}
   
}//end class Bud

public class Auktionsvare
{
private int vareNr;        //et unikt identifikationsnr.
private string beskrivelse;    //en beskrivelse af vare på auktion
private double startPris;
private Bud hoejesteBud;    //ass. til Bud objekt - det aktuelle højeste bud for denne vare

//Constructor
public Auktionsvare(int vareNr, string beskrivelse)
{
    this.vareNr = vareNr;
    this.beskrivelse = beskrivelse;
    this.startPris = 0;
}

public string Byd(Auktionskunde auktionsbyder, double budFraKunde, DateTime budTidspunkt)
{
    string serverBesked = null;
    if(this.hoejesteBud == null || this.hoejesteBud.GetPris() < budFraKunde)
    {
    this.SetHoejesteBud(new Bud(auktionsbyder, budFraKunde, budTidspunkt));
    serverBesked = "Ingen højere!";
    }
    else //dvs. hvis hoejesteBud != null og hoejesteBud.GetPris() > budFraKunde
    {
    serverBesked = "Budet på "+budFraKunde+" kr. er for lavt! "+budTidspunkt+" Giv nyt bud\r\n";
    serverBesked += "højesteBud er: "+this.hoejesteBud.GetPris()+" "+this.hoejesteBud.GetBudTidspunkt()+" "+auktionsbyder.GetNavn();
}
return serverBesked;
}
}//end class Auktionsvare


public class AuktionshusServer
{
HaandterKunde()
{
//send velkomst til kunde
serverBesked = "\rVelkommen til Bruuns Auktionshus! \rVare på auktion er: "+this.GetAuktionsvare().ToString()+"\rGiv bud";

monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
           
while(true)        //sålænge der kommunikeres med kunde 
{
    try
    {
    //server læser bud fra kunde
    budFraKunde = Convert.ToDouble(streamReader.ReadLine());
    budTidspunkt = DateTime.Now;    //budtidspunkt sat på serversiden

    Auktionskunde byder = new Auktionskunde(kundeIPadresse);
    Auktionsvare varePaaAuktion = this.GetAuktionsvare();
   
//her sættes budet + tidspunkt og sammenligning med aktuelt højeste bud gøres

    serverBesked = varePaaAuktion.Byd(byder, budFraKunde, budTidspunkt);

    etBud = varePaaAuktion.GetHoejesteBud();

    monitor.BroadcastAuktionsBud(etBud.GetAuktionskunde().GetNavn(), etBud.GetPris(), etBud.GetBudTidspunkt());
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, serverBesked);
    }
    catch(IOException)
    {
        break;
    }
               
    string hammerslag = null;

    //sammenligning af budtidspunkt med servertid
    while(true)
    {   
    DateTime nu = DateTime.Now;
    Thread.Sleep(1000);
    Console.WriteLine("start Budtidspunkt "+budTidspunkt);
    Console.WriteLine("start nu "+nu);

    if(etBud.GetBudTidspunkt().AddSeconds(18) >= nu)
    {       
    Console.WriteLine("budTidspunkt 3 "+etBud.GetBudTidspunkt().AddSeconds(18));
    Console.WriteLine("nu 3 "+nu);

    if(hammerslag != "tredie, varen er solgt!")
    {
    hammerslag = "tredie, varen er solgt!";
    Console.WriteLine(hammerslag);
           
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);        }
    }
    else if (etBud.GetBudTidspunkt().AddSeconds(15) >= nu)
    {
    if(hammerslag != "anden!")
    {
    Console.WriteLine("budTidspunkt 3 "+etBud.GetBudTidspunkt().AddSeconds(15));
    Console.WriteLine("nu 2 "+ nu);
    hammerslag = "anden!";
    Console.WriteLine(hammerslag);
                            monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);
    }
    }
    else if(etBud.GetBudTidspunkt().AddSeconds(10) >= nu)
    {   
    if(hammerslag != "første!")
    {
    Console.WriteLine("budTidspunkt 3 "+etBud.GetBudTidspunkt().AddSeconds(10));
    Console.WriteLine("nu 1 "+ nu);
    hammerslag = "første!";
    Console.WriteLine(hammerslag);
    monitor.BroadcastServerBeskedTilKunde(kundeIPadresse, hammerslag);   
    }
    }   

        }//end indre while løkke (hammerslag)
}//end ydre while løkke

}//end HaandterKunde
}//end class Auktionshusserver
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester