Archiv

Archive for the ‘.NET’ Category

Avoid subscribing to events in constructors


While adopting a unit test I found a piece of code which looks pretty much like this one:

public Subscriber(Printer printer, string message)
{
    printer.Print += OnPrint;

    if (message == null)
    {
        throw new ArgumentNullException("message");
    }

    myMessage = message;
}

This is the constructor of a class called Subscriber. In the first statement it subscribes an external event. Afterwards it checks a message parameter and might throw an exception. The following question comes to my mind. What happens to the event when the exception is thrown? Is there some zombie object assigned to the Print multicast delegate? Indeed it is! When you have the following code:

var s = new Subscriber(printer, null);

You will get an exception, but the instance was created somehow. The assignment to the s variable did not happen because of the exception but it is there. Typically the instance would be deleted with the next garbage collector run, but not when someone keeps a reference. In case of the Subscriber the Printer class keeps a reference with its Print event and so it cannot be garbage collected. What makes it even worse is, that the event handler of the zombie instance is called when the Print event is raised.

So be very careful when subscribing to events in constructors. If anything they should appear as last statement.

Kategorien:.NET, Software allgemein

File System Redirector


Wenn man aus einem 32 Bit Prozess heraus versucht eine Anwendung zu starten die unter C:\Windows\System32 liegt, wird der Pfad direkt zu C:\Windows\SysWOW64 übersetzt. Der Grund dafür ist, dass unter System32 die 64 Bit files liegen und unter SysWOW64 die 32 Bit Versionen. Für die Umleitung ist der File System Redirector verantwortlich. Das ist zwar alles ganz praktische, aber was wenn man aus dem 32 Bit Prozess wirklich die 64 Bit Anwendung starten möchte?

Dieses Problem hatte ich zum Beispiel mit Visual Studio. Ich wollte ein Powershell Script per external Tool einbinden, welches alle Prozesse beendet, die eine bestimmte DLL geladen haben. Die 32 Bit Powershell kann aber scheinbar nicht die Module eines 64 Bit Prozesses auflisten. Deshalb muss man die 64 Bit Version verwenden. Also habe ich im VS C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe als external Tool angegeben. Seltsamerweise hat dann mein Script aber nicht funktioniert. Nach etwas Suchen habe ich im process explorer gesehen,  dass immer die 32 Bit Powershell gestartet wird. Obwohl ich extra die 64  Bit Version angegeben habe. Stackoverflow brachte mich dann auf den File System Redirector und die Lösung für mein Problem. Man muss %windir%\sysnative als system Pfad verwenden. Dieser wird dann auch nicht geändert. Es muss also %windir%\sysnative\WindowsPowerShell\v1.0\powershell.exe als external Tool angegeben werden.

Kategorien:.NET, Software allgemein

dodned Usergroup Franken

1. April 2011 4 Kommentare

Gestern war ich zum ersten Mal auf einem Treffen der dotned Usergroup Franken und habe auch zum ersten Mal an einem coding dojo teilgenommen.

Es war wirklich sehr Witzig das FizzBuzz „Problem“ mittels TDD und mit pair programming zu lösen. Trotz der einfachen Natur der Aufgabenstellung ist es interessant wie viele Diskussionen es  über die Implementierung der Lösung gab. Das zeigt eines ganz deutlich: Kein Problem ist so einfach, als dass man es mit VHIT (vom Hirn ins Terminal) lösen sollte.

Beim nächsten Treffen bin ich auch wieder dabei 😉

Kategorien:.NET, Software allgemein

SharpRipLib

24. Februar 2011 6 Kommentare

Mein erstes eigenes open source Projekt! SharpRipLib ist ein C# Wrapper für die in C geschriebene CD Ripping Library. Mit diesem Projekt soll es möglich sein, Audio CDs mit .NET zu rippen. Ein wenig Code ist auch schon da. Wer mag, darf gern mit helfen!  😉

SharpRipLib

Kategorien:.NET, Software allgemein

Parallele Programmierung mit dem .NET Framework


Am 08.12.10 halte ich einen Webcast über die Task Parallel Library. Schaut doch mal rein wenn Ihr Zeit habt. Anmelden kann man sich hier.

Kategorien:.NET, Software allgemein

Enumerations als bit fields verwenden


Als ich letztens einen Unittest schrieb, fiel mir auf, dass ich in vielen Tests immer wieder die selbe Methode des Testees aufrief. Alles was sich änderte waren die Stubs und die Mock Objekte. Das Ganze sah ziemlich schlecht aus. Es musste sich doch irgendwie vereinfachen lassen. Ich versuchte also den Code in eine neue Methode auszulagern. Diese könnte ich dann von meinen Tests aus aufrufen. Aber wie konnte ich die Parameter so gestalten, dass die Signatur übersichtlich blieb? Da fiel mir ein, dass ich schon mal irgendwo gesehen hatte wie man enumerations als bit fields verwenden kann:

Ausgangspunkt soll folgendes enum sein:

public enum Colors
{
    None,
    Red,
    Green,
    Blue
}

Da enumerations eine Art name/value pair collection sind, kann man jeden Eintrag auf eine Zahl mappen. Die folgende Schleife tut dies für die Werte 0 bis 7 und gibt den Namen aus:

for (int i = 0; i < 8; i++)
{
    Console.WriteLine("{0,3} - {1}", i, ((Colors)i).ToString());
}

Das enum von oben liefert folgendes Ergebnis:

0 – None
1 – Red
2 – Green
3 – Blue
4 – 4
5 – 5
6 – 6
7 – 7

Das ist recht unspektakulär. Der C# Compiler hat einfach für jeden Eintrag im enum einen Zahlenwert vergeben. Von 0 beginnend, bis 3. Wenn man die Enumeration um das Flags Attribut ergänzt, ändert sich die Ausgabe noch nicht wirklich. Eigentlich traurig, weil man das enum dann immer noch nicht als Bitfeld verwenden kann.

Bei einem binären wert von 0011 ist nicht klar ob hier Rot und Grün oder nur Blau gemein ist. Deshalb müssen wir das enum noch ein wenig ändern:

[Flags]
private enum Colors
{
    None = 0,
    Red = 1,
    Green = 2,
    Blue = 4
}

Hier wurden jetzt neben dem Flags Attribut noch die Nummern von Hand vergeben. Damit kann man verhindern, das Bau anstelle der 3 die 4 bekommt. Binär sieht das dann so aus:

0000 – None
0001 – Red
0010 – Green
0100 – Blue

Wenn nun wieder die Schleife von weiter oben ausgeführt wird, sieht das Ergebnis ganz anders aus:

0 – None
1 – Red
2 – Green
3 – Red, Green
4 – Blue
5 – Red, Blue
6 – Green, Blue
7 – Red, Green, Blue

Das liegt daran, dass zum Beispiel die 7 binär eine 111 ist. Es ist also das bit für Rot, Grün und Blau gesetzt.

Nun könnte man sich eine Methode mit folgender Signatur bauen:

public void SetColors( Colors color )

Das schöne ist jetzt das man nicht nur eine sondern mehrere Farben vergeben kann. Zum Beispiel Rot und Grün:

SetColors( Colors.Red | Colors.Green  )

Rot und Grün wird mit einem binären ODER verknüpft das ergibt dann den Wert: 0011. Dieser wird an die Methode übergeben.

Innerhalb von SetColors kann man dann mit folgendem Code prüfen, welche Farben aktiv sind:

public static void SetColors(Colors colors)
{
    if (IsColorSet(colors, Colors.Red))
    {
        //Do something
    }

     // ...
}

private bool IsColorSet(Colors colors, Colors colorToCheckFor)
{
    return (colors & colorToCheckFor) == colorToCheckFor;
}

Der kombinierte Wert wird also mit einem logischen UND mit dem zu prüfenden Wert verknüpft. Dadurch werden alle Bits gekippt, die nicht im zu prüfendem Wert 1 sind.
Bei Rot und Grün haben wir zum Beispiel 0011. Nur Rot ist die 0001. Und aus 0011 & 0001 wird 0001. Also wieder Rot.

Enumerations sind zusammen mit dem Flag Attribut also sehr gut geeignet um Optionen weiterzugeben, bei den auch verschieden Kombinationen möglich sind.

Kategorien:.NET

SQL Server Compact Edition


Vor kurzem habe ich die Compact Edition des SQL Servers ausprobiert. Diese gibt es ja schon länger, aber ich dachte immer sie währe nur für mobile Geräte nützlich. Doch weit gefehlt. Wenn man dem Nutzer seiner Anwendung das installieren eines SQL Servers ersparen will, kann man einfach die dll’s der CE Version mit deployen. Mehr ist nämlich nicht nötig und so muss nicht immer eine SQL Server Instance im Hintergrund laufen.

Wenn man eine Anwendung mit der CE Edition entwickeln möchte, muss man sich diese zuerst installieren. Dabei wird, wie gesagt, aber keine Instance angelegt. Es werden lediglich dll’s auf die Platte kopiert. Die Datenbank erstellt man am besten mit dem SQL Server Management Studio. Dazu bei Server type einfach SQL Server Compact Edition angeben und bei Database file „new Database“ wählen. Danach noch den Anweisungen folgen. Das Ganze funktioniert leider nur mit der 2008er Version des Management Studios. Was man, soweit ich weiß, nicht einzeln herunterladen kann.

Wenn man seine Datenbank erstellt hat, bedient man sie am besten mit Linq to SQL. Seinen Mapper Code kann man sich von sqlmetal erstellen lassen, dass beim Visual Studio und im .NET SDK dabei ist:

sqlmetal e:\TimeProofer.sdf /namespa ce:MyNamespace /password:mypass /code:TimeProofer.cs

Das erstellte Codefile kann man dann in sein Projekt einfügen und zum Beispiel so verwenden:

TimeProofer tp = new TimeProofer("Data Source=E:\\TimeProofer.sdf;Password=mypass");
Project project = new Project();
project.Proj_name = "My new Project";
project.Proj_description = "With this description";

tp.Project.InsertOnSubmit(project);
tp.SubmitChanges();

foreach (var projects in from p in tp.Project select p)
{
    Console.WriteLine(project.Proj_name);
}

Zuerst wir eine neue Instance der TimeProofer Klasse angelegt. Als Parameter wird ein ConnectionString verwendet. Nun kann ein neues Projekt angelegt werden. Project ist übrigens eine Tabelle in meiner Datenbank.  Das neue Projekt wird dann der Projekttabelle hinzugefügt und submitted. Abfragen kann man seine Tabelle mit der Linq typischen Syntax.

Alles in allem kommt man so ziemlich schnell zu einer einfachen Datenbankschicht, die für kleine Anwendungen vollkommen ausreichen ist.

Hier noch ein Link zu SQL Server CE:

http://www.microsoft.com/sqlserver/2005/en/us/compact.aspx

Kategorien:.NET, SQL Server