Tool-Tip: dotTRACE

Hui, hier ist ja schon lange nichts mehr passiert seh ich gerade, dann wirds aber mal wieder höchste Zeit für einen Beitrag 😀 Ich war neulich dazu gezwungen mir mal den genauen Start-Ablauf einer von mir entwickelten Anwendung anzuschauen, da diese eine recht lange Ladezeit hatte und ich mir einfach nicht erklären konnte wo die herkommt. Die Anwendung verwendet allerhand Drittanbieter-Bibliotheken, unter anderem auch NHibernate und FluentNHibernate als Aufsatz und ich hatte diese beiden im Verdacht für die schlechte Startperformance verantwortlich zu sein. Natürlich sucht man die Schuld erstmal bei jemand anderem, das ist ja logisch 😉 Nach einigem Google-Consulting bin ich dann darauf gestoßen, dass ich das Problem, wie so oft im Leben, nicht alleine habe und das jemand anders dafür auch schon eine Lösung gefunden hat. Um das Problem zu finden benutzte derjenige einen sogenannten Profiler namens dotTRACE von jetbrains. Dieses Tool zeigt einem exakt welche Schritte seine Anwendung durchläuft und wieviel Zeit diese Schritte gekostet haben. Da sieht man meistens sofort wer für das Performanceproblem verantwortlich ist. Ich hab das dann auch mal installiert und konnte dann das gleiche Problem auch bei mir feststellen. Genial dieses Tool! Tatsächlich war FluentNHibernate schuld. Genauer gesagt war das Problem eine Routine bei der Initialisierung der Konfiguration durch FluentNH. Dank dotTrace konnte ich sehen das da intern beim generieren der Konfiguration ein XML-Dokument erstellt wird, was ein vergleichsweise zeit/rechen-intensiver Vorgang ist. Das macht FluentNH bei jedem Startvorgang, auch wenn sich an der Konfiguration nichts geändert hat. Als Lösung gab er an diese Konfiguration als Binary-File abzuspeichern und diese beim Laden einfach einzuwerfen anstatt FluentNH das immer wieder neu generieren zu lassen und das hat mir letztendlich mehr als die Hälfte der Ladezeit eingespart. Großartig, dafür liebe ich das Internet 🙂 Abschließend muss ich diesem hervorragenden Tool aber noch einen halben Punkt in der B-Note abziehen, für das schlechte Anchoring des Fensters. Aber ansonsten bekommt's von mir eine absolute Empfehlung!  

BASTA!Spring 2010 – Mein Fazit

Auch dieses Jahr war ich wieder Teilnehmer der Frühjahrausgabe der Konferenz für .NET Entwickler BASTA!. Hinter mir liegen 4 Tage voller teils sehr interessanter und unterhaltsamer Vorträge aus allen Bereichen der .NET-Welt. Hier mal ein paar Dinge die ich dazugelernt habe: Das Keyword "var" wurde nicht etwa nur erfunden damit man nicht mehr explizit den Typ einer Variablen angeben muss, sondern um Anonyme Typen darstellen zu können. Das war mir bisher irgendwie entgangen 😉 IPhone Anwendungen muss man nicht in Objective C schreiben, es geht auch in C#. Mit der Hilfe eines Apple Rechners, der Entwicklungsumgebung MonoDevelop (kostenlos) und einer MonoTouch Lizenz (400€) kann man eine C# Anwendung zu einer IPhone App kompilieren. Dazu gabs eine schöne Live-Demo, sah relativ einfach aus. Debugger Habt ihr im Visual Studio 2008 schon mal mit der rechten Maustaste auf einen Breakpoint geklickt? Ich leider nicht, daher sind mir einige sehr hilfreiche Funktionen bisher entgangen... Zum Beispiel kann man hier eine "Bedingung" festlegen die erfüllt sein muss, damit der Debugger die Anwendung anhält. Die "Trefferanzahl" ermöglicht es einem festzulegen, dass der Debugger beispielsweise erst beim 5. Erreichen des Breakpoints das Program anhält und nicht jedesmal! Mit "Bei Treffer" kann dem Breakpoint ein Makro hinterlegt werden, dass bei Erreichen ausgeführt wird. Das neue Visual Studio 2010 kommt allerdings mit einem Hammer-Feature daher, und das heisst "Rückwärts-Debugger". Man kann nun endlich im Programmablauf in der Zeit zurückspringen und sich jeden Zustand anschauen den man will. Leider wird dieses "IntelliTrace" nur in der teuersten Ultimate Version enthalten sein die ca. 2 Scheine kosten wird. TFS 2010 ist die neuste Version vom Team Foundation Server und dieser soll sich  im Gegensatz zu seinem Vorgänger sehr einfach (in ca. 20 Minuten) in Betrieb nehmen lassen und man braucht kein Server-Betriebsystem mehr dazu. Das hier integrierte Code-Versions-Verwaltungssystem ist der Nachfolger vom bisherigen "SourceSafe" und bietet auch sehr kleinen Teams sehr gute Kontrolle über gemeinsame Projekte. TFS enthält auch einen Issue bzw. Bug-Tracker und man kann WorkItems verwalten. Damit lässt sich quasi der komplette Lebenszyklus einer Anwendung abbilden. Sehr schönes Teil wie ich finde. Besitzer einer MSDN-Subscription bekommen das Teil mit einer 5 Benutzer Lizenz wohl schon recht günstig. Das MVVM Pattern (Model-Viev-ViewModel) ist ein Design Pattern, dass häufig bei WPF/Silverlight Projekten zum Einsatz kommt. Hierzu gibt es einen sehr schönen Beitrag auf Codeprojekt von Rainer Stropek wo gezeigt wird, wie das Entwurfsmuster angewendet wird und wie man damit eine wiederverwendbare Codebasis schaffen kann, die sowohl für WPF als auch für Silverlight Projekte gleichermaßen einsetzbar ist. An dieser Stelle möchte ich auch mal ein richtig dickes Lob an Rainer Stropek rausschicken. Er hat während der BASTA mehrere sehr gute und vorallem praxisnahe, Vorträge gehalten die mich wirklich weiter gebracht haben. Danke dafür, weiter so! IronPython ermöglicht die direkte Nutzung der sehr mächtigen Skriptsprache Python aus .NET Assemblies heraus. Hier gabs ein schönes Praxisbeispiel zu sehen in Verbindung mit dem HTML/XML Parser BeautifulSoup für Python, welcher einfaches ScreenScraping ermöglicht. Ist auf jeden Fall einen Blick wert! CodeContracts bieten eine sehr schöne Möglichkeit um Validierungslogik zu implementieren. Anstatt viele If-Anweisungen oder try/catch Blöcke in die Ablauflogik zu packen kann man beispielsweise mit dem Attribut  "Contract.Reqire(...)" über einer Methode oder einem Property eine entsprechende Gültigkeitsbedingung festlegen. Das sieht nicht nur sauberer aus, sondern ist auch deutlich besser testbar. Ist auf jedenfall empfehlenswert, wenn man sehr viele Gültigkeitsbedingungen abzuprüfen hat. RhinoMocks und MOQ sind zwei gute Mocking-Frameworks um Objekte bzw, Verhalten zu "simulieren". Es geht darum Code testbar zu machen in dem Abhägigkeiten "gemockt" werden. Das Ziel ist es, dass ein Testfall nur maximal EINEN Grund haben darf um zu scheitern und nicht mehrere. Sobald aber mein Testfall eine Abhägigkeit hat wie z.B. ein Zugriff auf eine Datenbankverbindung oder einen Webservice habe ich mehrere potentielle Fehlerfälle zu betrachten. Hier springen die Mockobjekte in die Bresche, mit denen man bestimmte Dienste, Rückgabewerte oder Abläufe simulieren kann, obwohl diese evtl. nicht erreichbar bzw. noch garnicht implementiert sind. Damit ist man in der Lage einzelne Dinge zu testen ohne auf die Abhängigkeiten eingehen zu müssen. Zum Thema "Geschwindigkeitsoptimierung" von Anwendungen gab es auch einen schönen Vortrag zu hören in dem auf Möglichkeiten eingegangen wurde, wie man seine Anwendung schneller machen kann. Das betrifft vorallem Anwendungen die viel rechnen müssen bzw, die sehr komplexe Algorithmen durchlaufen. Beispielweise ist die Verwendung von "struct" deutlich besser für die Performance einer Anwendung als bei der Nutzung einer Klasse und Methodenaufrufe in flachen Objekten sind deutlich schneller als bei Objekten die ein Interface implementieren bzw. die von einer Klasse erben. Um Performance von Anwendungen zu messen sollte man dotTrace von jetbrains verwenden. Das ist mit Sicherheit besser als jeglicher handgestrickter Kram. Sehr unterhaltsam war der Vortrag "Why software sucks" von David Platt. Der Mann ist Amerikaner und ein echter Entertainer! Er hat auf sehr amüsante Weise ausgesprochen, was die meisten Entwickler eigentlich nicht hören wollen: "Kein Schwein interessiert sich für deine Software". Leider hat er damit sehr recht, denn Anwender nutzen Software um ihre Arbeit zu erledigen und sonst für nichts. Es interessiert wirklich keinen Anwender wie Software gemacht ist und was alles für spannende Technologien drin verbaut wurden. Es geht dem Benutzer nur darum seine Arbeit zu erledigen bzw. einen Zustand der Zufriedenheit herzustellen. Deshalb sollten alle Entwickler immer darauf achten das Software einfach zu benutzen ist und möglichst kein Handbuch notwendig ist um sie zu verstehen. Es sollten nur Dinge implementiert werden die wirklich gebraucht werden. Maximale Flexibilität in einer Anwendung heisst oft leider auch zu viele unübersichtliche Features die oft eher zu Frustration des Benutzers führen als zur Zufriedenheit.
Don't let your software suck! Make it just work!
So, das soll reichen. Neben den vielen Informationen gabs natürlich auch wieder sehr gutes Essen! Daher möchte ich noch den Veranstalter loben, insbesondere die Küchencrew vom Maritim Hotel in Darmstadt. Das war mal wieder eine Schlemmerwoche vom Allerfeinsten, Super Leistung 😀 Na dann hoffentlich bis nächstes Jahr...

ClickOnce und OracleClient…

... sind Dinge, mit denen ich mich derzeit auf der Arbeit rumschlage. 1 Ich entwickle derzeit eine Client-Anwendung für interne Zwecke, welche auf ca. 10 Rechnern laufen soll. Damit man diese nun nicht alle aufwendig manuell installieren bzw. später updaten muss habe ich mich für ClickOnce als Deployment-Lösung entschieden. Ich habe damit bereits gute Erfahrungen bei  einer anderen Anwendung gemacht, die ich regelmäßig anpasse und neu verteile. Diese neue Anwendung soll nun allerdings im Gegensatz zur vorherigen mit einer Datenbank kommunizieren, und zwar genauer gesagt mit einer Oracle 10g. Gesagt, getan: Als erstes verweise ich in meiner Anwendung auf den Namensraum "System.Data.OracleClient". Beim Start der Anwendung bekomme ich allerdings gleich beim ersten Verbindungsversuch folgende Meldung zu sehen: Will man nun sein Programm starten stößt man beim Verbindungsaufbau auf den nächsten Fehler.2 Im Gegensatz zu den meisten anderen  Datenbanken erfordern Oracle Datenbanken leider die Oracle eigene Clientsoftware, denn der System.Data.OracleClient macht nichts weiter als mit genau diesem Client zu kommunizieren. 3 Nun muss man sich den zu seiner Datenbank-Version passenden OracleClient runterladen und installieren. Hat man dies ordnungsgemäß getan sollte man seine Anwendung auch starten können. Das ist für mich allerdings nur eine suboptimale Lösung, denn ich will ja mein Programm via ClickOnce ausrollen und keine separate manuelle Installation des OracleClients auf jedem Rechner vornehmen. Man könnte das ausrollen des Clients via Software-Verteilung vornehmen (wenn man eine hat), aber es gibt noch eine viel elegantere Lösung. Um jetzt den ClickOnce Vorteil zu behalten müssen wir also die Clientsoftware in unsere Software "Veröffentlichung" (Publish) mit einbeziehen. Das geht leichter als man denkt, denn das ganze Geheimnis der Oracle-Clientsoftware sind lediglich 4 Dateien, welche man einfach nur in sein Projekt aufnehmen braucht. 4 Die werden allerdings nicht als Verweis hinzugefügt, sondern einfach als normaler Content ins Projekt gezogen. Sie müssen hier unbedingt im Root des Projektes liegen und beim Build mit ins Ausgabeverzeichnis kopiert werden (Eigenschaften), weil sie von der Anwendung beim Start im selbigen Ordner gesucht werden wie die Anwendungs-EXE.5 Als nächstes gilt es noch, falls nicht bereits automatisch geschehen, diese Dateien zu markieren, damit sie beim Publish mit verteilt werden.(Settings=>Publish) Bei der Auswahl der Oracle-Clientsoftware gilt es übrigens zu beachten die 4 Dateien aus dem sogenannten "BASIC" Paket zu nehmen und nicht die aus dem "BASIC LITE". Die "LITE"-Versionen verursachten folgenden Fehler: instant_client_basic_lite_fehler Nach dem nächsten Publish sollte die Anwendung dann startbar sein. War leicht oder? Nagut, einen kleinen Wermutstropfen gibt es natürlich noch. Eine der vier ominösen DLLs ist schlappe 104 MB groß, d.h. das Publish-Paket ist nun nicht mehr das kleinste, was allerdings bei uns im LAN keine Rolle spielt. In diesem Zusammenhang war dieser Beitrag sehr hilfreich und sei hiermit auch sehr zu empfehlen. Ach übrigens: Der GAC befindet sich in Windows XP unter "C:\Windows\Assembly" und die "gacutil.exe" ist unter "C:\Programme\Microsoft Visual Studio 8\SDK\v2.0\Bin\". In diesem Sinne, happy coding 🙂

Unit-Testergebnisse dokumentieren

Ich beschäftige mich derzeit mit Unit-Tests, da ich als Black-Box-Tester einer Klassenbibliothek auserkoren wurde. Nun denn, eigentlich kein Problem. Man erstellt sich ein neues Projekt, lädt die Klassenbibliothek als Verweis rein und fängt an Testklassen/Testmethoden zu definieren, welche einzelne Teile der DLL aufrufen und durchtesten. Bis dahin alles kein Problem. Aber was, wenn man die Testergebnisse ausdrucken muss? In der Medizintechnik-Branche wird viel wert auf die Dokumentation gelegt, da reicht ein einfaches durchlaufen nicht aus, das muss alles ausgedruckt und an den Testplan mit rangehangen werden. Fragt sich nur wie? Ich setze das NUnit-Framework zum Testen ein. Das macht sich auch ganz gut dafür, nur es gibt leider keine Möglichkeit ein vernünftiges Protokoll des Testdurchlaufs davon zu drucken. Ich brauche Testfallnummer, Testfallname, Testdaten, Ergebnisdaten und ob der Test bestanden wurde. Das ganze möglichst übersichtlich und schick. Wie es aussieht bleibt mir wohl nichts anderes übrig, als diese Werte während des Testfall-Durchlaufs via Console.WriteLine an die Logausgabe zu schicken und dann den Log-Output zu drucken. Geht das nicht auch anders? Ich weigere mich zu glauben das es dafür keine vernünftige Lösung gibt! Hat jemand damit Erfahrung und einen Tip für mich?

[Tutorial] .NET Programme vom Netzlaufwerk starten

Endlich, mein erster .NET Beitrag ist fertig. UPDATE Hier findet ihr noch einen sehr guten Artikel zu diesem Thema, unbedingt lesen! Also ich hatte da neulich das Problem das ich ein C#-Programm für mehrere Personen im Netzwerk zugänglich machen wollte OHNE es überall installieren zu wollen/müssen. Das ist aber bei .NET so eine Sache, denn die CAS (Code Acess Security) ist da recht restriktiv was IO-Operationen über das Netzwerk angeht und deshalb gabs beim Starten auf dem entfernten Rechner erstmal eine nette SecurityException als Antwort. Gut, also was tun. Man muss nun auf jedem Rechner der das Programm starten können soll die Laufzeit-Sicherheits-Richtlinie so modifizieren das er der Assembly vertraut. Das ist relativ einfach und soll auf den folgenden Bildern gezeigt werden. Erstmal begibt man sich in die Systemsteuerung und dort dann in die Verwaltung. Hier sieht man nun die sogenannte .NET Konfiguration für alle installierten Versionen des Frameworks. Beim 1.1er war dieser Menüpunkt immer vorhanden, aber seit dem 2.0er gilt das nur noch wenn man die SDK installiert hat. Stellt sich nun die Frage: Wie komme ich beim 2.0er dahin? Muss ich nun auf jedem Rechner die SDK installieren? Antwort: NEIN, aber dazu später mehr. Erstmal zeige ich wie man es zu Fuß macht. Verwaltung „[Tutorial] .NET Programme vom Netzlaufwerk starten“ weiterlesen