#1 16. Februar 2011 Zuletzt von einem Moderator bearbeitet: 14. April 2017 Ampelsteuerung Hoi, ein User fragte mich hier, ob ich ihm eine Ampel programmieren könne mit C#. Nachdem ich erfahren habe, was es können soll habe ich mich dran gegeben. Ist eigentlich nichts besonderes, aber was hier für einige interessant sein kann ist, dass es einen automatischen Ablauf der Ampel im neuen Thread gibt und eine Aktualisierung der GUI. Zudem habe ich die Bilder in die Ressourcen gepackt. Ich zeige als auch, wie ich die Bilder wechsle. Die Ampel Klasse: PHP: namespace pAmpel { class cAmpel { private AmpelZustand zustand ; public cAmpel () { zustand = AmpelZustand . Stop ; } public AmpelZustand Zustand { get { return zustand ; } set { zustand = value ; } } public void schalteNaechsten () { switch ( zustand ) { case AmpelZustand . Stop : zustand = AmpelZustand . Ready ; break; case AmpelZustand . Ready : zustand = AmpelZustand . Go ; break; case AmpelZustand . Go : zustand = AmpelZustand . Brake ; break; case AmpelZustand . Brake : zustand = AmpelZustand . Stop ; break; } } public void Durchlauf ( object data ) { for ( int i = 0 ; i < 4 ; i ++) { System . Threading . Thread . Sleep ((int) data ); schalteNaechsten (); } } } enum AmpelZustand { Stop , Ready , Brake , Go } } Die Funktion, mit der die Ampel gestartet wird (der komplette Durchlauf): PHP: private void bDurchlauf_Click ( object sender , EventArgs e ) { Thread t = new Thread (new ParameterizedThreadStart ( ampel . Durchlauf )); int waitTime ; try { waitTime = Convert . ToInt32 ( tBTimeForState . Text ); } catch ( Exception ) { //default: 2 sec for each state waitTime = 2000 ; } t . Start ((object) waitTime ); do { changeColor (); this . Update (); } while ( t . IsAlive ); //to ensure that the colors will change after the thread finished changeColor (); } Die Funktion, mit der ich auf die Resourcen zugreife und die Bilder wechsle: PHP: private void changeColor () { switch ( ampel . Zustand ) { case AmpelZustand . Stop : pBRed . Image = Resources . red_active ; pBYellow . Image = Resources . yellow_passive ; pBGreen . Image = Resources . green_passive ; break; case AmpelZustand . Ready : pBRed . Image = Resources . red_active ; pBYellow . Image = Resources . yellow_active ; pBGreen . Image = Resources . green_passive ; break; case AmpelZustand . Go : pBRed . Image = Resources . red_passive ; pBYellow . Image = Resources . yellow_passive ; pBGreen . Image = Resources . green_active ; break; case AmpelZustand . Brake : pBRed . Image = Resources . red_passive ; pBYellow . Image = Resources . yellow_active ; pBGreen . Image = Resources . green_passive ; break; } Zum Schluss noch das ganze Projekt: Download: pAmpel.rar | www.xup.in Habe die Binaries rausgelassen, aber selbst kompilieren sollte mit einem Knopfdrücken klappen greeez + Multi-Zitat Zitieren
#2 16. Februar 2011 AW: Ampelsteuerung Wieso hast du Code: public void Durchlauf(object data) und nicht Code: public void Durchlauf(int waittime) genutzt? Du castest doch sowieso wieder nach int. + Multi-Zitat Zitieren
#3 16. Februar 2011 AW: Ampelsteuerung Das ist eine gute Frage. Das musste ich tun, da new ParameterizedThreadStart() als Parameter einen Delegat haben wollte, der als Parameter ein Objekt haben will. Deshalb musste ich in Durchlauf als Parameter ein Objekt vom Typ object nehmen, sonst hätte es vor der Kompilierung schon Probleme gegeben. Versuch es mal und du wirst sehen, dass es nicht funktioniert. Der Vorteil ist, dass man eigene Strukturen und sowas also Object übergeben kann (beispielsweise ein Array), in dem dann alle benötigten Parameter vorkommen. (Man übergibt weiterhin aber nur ein Object). greez edit: ParameterizedThreadStart-Delegat (System.Threading) + Multi-Zitat Zitieren
#4 16. Februar 2011 AW: Ampelsteuerung Okay stimmt, aber elegant finde ich das nicht unbedingt. Ich benutze dafür lieber Lambda-Expressions: Code: private void bDurchlauf_Click(object sender, EventArgs e) { int waitTime; try { waitTime = Convert.ToInt32(tBTimeForState.Text); } catch (Exception) { //default: 2 sec for each state waitTime = 2000; } [B]Thread t = new Thread(() => ampel.Durchlauf(waitTime)); t.Start();[/B] do { changeColor(); this.Update(); } while (t.IsAlive); //to ensure that the colors will change after the thread finished changeColor(); } Dann kann man die Methode Durchlauf auch mit einem int-Argument schreiben. + Multi-Zitat Zitieren
#5 16. Februar 2011 AW: Ampelsteuerung Ich denke, dass das Haarspalterei ist und Lambda Ausdrücke für viele, die was lernen möchten und gerade erst anfangen, doch recht schwer sind. Daher hab ich die übliche Methode genommen und meiner Meinung nach lässt die sich auch ein wenig besser nachvollziehen (aber du hast Recht, mit deiner Methoed kann man auch wieder einen int als Parameter Typ nehmen) greez + Multi-Zitat Zitieren
#6 16. Februar 2011 AW: Ampelsteuerung Das stimmt natürlich auch wieder :] Was ich allerdings noch ganz interessant fand, war der Zugriff auf die Resourcen. Ich habe mich damit bisher nie beschäftigt und wusste gar nicht, dass es da eine so elegante Möglichkeit für gibt. Mir war bisher nur der Zugriff über Assembly.GetManifestResourceStream bekannt. Wieder was dazugelernt + Multi-Zitat Zitieren