Alles Gute zum Geburtstag! 3 Jahre Flurfunk… 23.05.2013

Alexander Jung
Svenja Henß, Senior Assistant

Vor 3 Jahren ging der Flurfunk an den Start, der erste Beitrag erschien am 28.05.2010.

Herzlichen Glückwunsch! Und Zeit für etwas Selbstbeschau…

 

Engine hinter dem Flurfunk ist blogger.com und wie jede Blog-Engine verfügt natürlich auch Blogger über diverse Zugriffsstatistiken. Und je länger ein Blog live ist – je größer also die Datenbasis – desto aussagekräftiger werden Statistiken naturgemäß.

Während ich diesen Beitrag schreibe stehen 512 Beiträge in der Liste. Auch wenn das noch unveröffentlichte Beiträge (und sicher auch die eine oder andere Leiche) einschließt, eine stattliche Zahl. Daraus ergeben sich im Schnitt 170 Beiträge pro Jahr, oder 14 pro Monat. Fast jeden zweiten Tag ein Beitrag? Nicht schlecht.

Und die Zugriffszahlen zeigen ein kontinuierliches Wachstum, mit unseren Themen können wir also so verkehrt nicht liegen Zwinkerndes Smiley:

image

 

Die Beiträge mit den höchsten Zugriffszahlen sind:

  1. Two-Way Databinding für Cascading DropDownList
  2. Windows 8 Tip: Beliebige Programme in der Startseite aufnehmen
  3. WCF LiveID Authentication einer Windows 8 Store App – Teil 1

Platz 1 ist dabei erklärbar durch die Verlinkung in einem Forum. Die anderen beiden deuten auf die Bedeutung von Windows 8 hin.

Falls die BI-Kollegen sich jetzt fragen, wo ihr Beitrag ist: Beiträge zu BI-Themen und SharePoint finden sich sehr wohl in der Statistik, aber es gibt eben nicht den herausragenden Beitrag.

PS: Ich habe gelogen, auf Platz 1 liegt der Willkommensbeitrag. Aber den sehe ich außer Konkurrenz Zwinkerndes Smiley.

Ganz interessant finde ich auch, woher unsere Leser kommen:

Grafik der unter Blog-Lesern beliebtesten Länder

Dass das Gros der Zugriffe mit 75% aus Deutschland kommt (dazu 3% aus Österreich und Schweiz) ist bei einem deutschsprachigen Blog nicht verwunderlich. Aber 13% aus USA? Dazu China, Frankreich und UK mit jeweils über 2%? Da ist Russland mit 1% ziemlich abgeschlagen.

Spanien und Niederlande tauchen noch mit jeweils 0,4% auf, aber das möchte ich nicht weiter kommentieren Zwinkerndes Smiley

 

Die Browser- und Betriebssystem-Verteilung dürfte hingegen keine allzu große Überraschung sein:

Bild, das die beliebtesten Browser zeigt   Bild, das die beliebtesten Plattformen zeigt

Der Firefox hat mit 42% auch bei unserem – vermutlich Microsoft-affinen – Publikum den Internet Explorer mit 37% überholt. Dass Windows mit 79% domminiert war ebenfalls zu erwarten, eher schon ist der Anteil der Zugriffe von mobilen Geräten untypisch gering.

 

3 Jahre Flurfunk heißt vor allem zwei Dinge:

  1. Viele Leute bei SDX, die Beiträge schreiben oder die organisatorische Arbeit hinter den Kulissen erledigen.
  2. Leser, die das offensichtlich honorieren.

 

Danke an beide!

Share |

Die zwei Gesichter von Windows 8: Windows Store Apps vs. Desktop 21.05.2013

Alexander Jung
Alexander Jung, Chief eXpert

Wie ich im letzten Beitrag Schlechtes Marketing und Unverständnis beleuchtet habe, kommt Windows 8 mit zwei Gesichtern – einem alten (Desktop) und einem neuen (Windows Store Apps) – daher. Und Microsoft macht nicht wirklich eine gute Figur darin, den Anwendern das neue Gesicht nahezubringen, oder gar ihnen die Motivation offenzulegen.

Das Resultat ist entsprechend: Tests, die Windows 8 auf dem klassischen PC betrachten, erklären reihenweise, dass die neuen UI-Paradigmen auf diesem umständlich sind und den Anwender verwirren. Tests von Windows 8 auf Touch-Devices weisen auf die Unzulänglichkeiten von klassischen Anwendungen hin. Und jeder fragt, warum das so sein muss.

Die Antwort ist im Grunde ganz einfach – nur scheinbar nicht offensichtlich: Microsoft möchte Geld verdienen, auch in Zukunft.

Geld verdienen, indem sie die Anwender verwirren? Wie passt das zusammen?

 

Zunächst muss man verstehen, was Microsoft mit Windows 8 eigentlich gebaut hat…

Wichtig ist, dass es sich bei Windows Store Apps („Metro“, „modern UI“) und Desktop (“Classic”) tatsächlich um zwei Systeme handelt.

Das typische Bild, das Microsoft einem Entwickler vorlegt lässt sich vereinfachen zu drei groben Blöcken:

  • Als gemeinsamer Unterbau der Kernel (MinWin).
  • Darauf aufbauend die Win32-basierte alte Welt – zu der auch COM und .NET gehören – der Desktop Anwendungen.
  • Ebenfalls darauf aufbauend, aber als unabhängige zweite Säule daneben: Die neue Welt der Windows Store Apps.

Win8_Architecture_Overview

Microsoft hat hier im Grunde das Kunststück geschafft, auf dem gleichen Kernel zwei Betriebssysteme parallel hochzuziehen und gleichzeitig auf dem Rechner laufen zu lassen.

Und darin liegt die Crux:

  • Desktop Anwendungen sind – jetzt und in Zukunft – für den Desktop gedacht. Maus- und Tastaturbedienung inklusive.
  • Windows Store Apps sind für Touch-Devices gedacht. Punkt.

Oder – um es noch deutlicher zu machen – andersherum:

  • Man kann Desktop-Anwendungen auch auf Touch-Devices laufen lassen 
    – aber das ist nicht ihre Bestimmung!
  • Windows Store Apps auf dem Desktop laufen zu lassen mag zwar ganz gut funktionieren
    – aber dafür sind diese Apps nicht gedacht!


Jetzt schaut sich der Leser sein Windows 8-System an und stellt fest, dass das bunt gemischt ist. Doch ein Widerspruch?

Die Frage nach dem Warum…

Wenn Startbildschirm und Windows Store Apps für Touch-Devices gedacht sind, und Desktop-Anwendungen für klassische PCs, warum dann ein Betriebssystem? Warum der (sicher nicht geringe) Aufwand und warum dem Anwender diese krude Mischung zumuten?
Warum nicht – wie es Apple und Google vorgemacht haben – zwei getrennte Wege gehen?

Ganz einfach: Microsoft hat nicht primär das Interesse, dem Anwender das Leben leicht zu machen. Microsoft ist eine auf Gewinnerzielung ausgerichtete Unternehmung, die nicht aus altruistischen Motiven handelt. (Das ist nicht per se schlecht, man sollte sich dessen nur bewusst sein.)

Gewinn – bzw. die dafür notwendigen Marktanteile – ist aber in absehbarer Zukunft nicht mit dem klassischen Desktop-Umfeld zu machen. PC-Verkäufe stagnieren oder gehen zurück, der Wachstumsbereich sind mobile Geräte, also Tablets und Smartphones. In diesen Bereichen muss Microsoft folglich einen Fuß in die Türe bekommen.

Stellt sich die Frage: Wie?

Microsoft und andere haben über die Jahre versucht, klassische Desktop-Betriebssysteme auf Touch-Devices zu bringen – mit mäßigem Erfolg. Erst das iPad und später Android haben gezeigt, dass das Betriebssystem für Touch-Devices andere Eigenschaften haben muss (z.B. Stromverbrauch optimieren) und dass die Bedienparadigmen andere sind, man also das UI nicht einfach übernehmen kann. Das hat dazu geführt, dass der Markt von iPad und Android dominiert wird und Microsoft ein Spätstarter ist.

Hätte Microsoft den gleichen Weg eingeschlagen wie Apple und Google und ein Touch-Device-optimiertes Betriebssystem separat neben dem normalen Windows entwickelt, wäre die Konsequenz ziemlich absehbar gewesen:

Dieses Touch-Betriebssystem wäre ein weiteres Nischenprodukt!

Es gäbe keine Software dafür, und die Windows-gewohnten Anwender müssten sich in das neue System genauso einarbeiten, wie in die Systeme der Konkurrenz. Ergo hätten die Anwender keinen Grund gehabt, diesem Nischenprodukt den Vorzug vor den Systemen der Konkurrenz zu geben, die Hardware-Hersteller hätten keine oder kaum Geräte gebaut, die Entwickler keine Software geschrieben.

Stattdessen verheiratet Microsoft den Touch-Betriebssystem-Aspekt mit dem bestehenden System – immerhin kein ganz triviales Unterfangen.

Die Konsequenzen daraus sind breit gefächert: Microsoft muss sich keine Sorgen machen um…

  • … die Verbreitung, denn das System läuft auf allen gängigen Rechnern.
  • … die Unterstützung seitens der Hardware-Hersteller, denn für diese ist das vergleichsweise risikolos.
  • … die Unterstützung seitens der App-Entwickler, denn eine App zu schreiben, die über das gesamte Windows-Ökosystem hinweg eingesetzt werden kann, ist keine schlechte Motivation.
  • … den Einsatz in Unternehmen, denn das System integriert sich nahtlos in die bestehende Infrastruktur – ganz im Gegensatz zur Konkurrenz.

Doch Microsoft geht noch einen Schritt weiter und zwingt dem Anwender die Touch-Aspekte auf seinem ganz normalen PC auf, was für diesen eher von Nachteil ist.

Hier kommt der vielleicht wichtigste Grund zum Tragen:

  • Die Anwender werden implizit auf das neue System geschult!

Auch wenn das sicher seine Zeit brauchen wird: Irgendwann werden die Anwender Windows 8 kennen, wissen wie sich Windows Store Apps bedienen lassen und sich an die zwei Welten – insbesondere auch die neue Welt der Windows Store Apps – gewöhnt haben.

Wenn dann ein Anwender ein Tablet sucht, wählt er dann das iPad oder ein Android? Oder wird er das Gerät wählen, auf dem das gleiche Betriebssystem läuft, das er jeden Tag im Büro verwendet? Mit der gleichen Software?
Die Antwort wird vielleicht nicht immer Windows 8 lauten, aber deutlich öfter, als sie “Ein Touch-Betriebssystem von Microsoft neben Windows” gelautet hätte.

 

Für den umgekehrten Fall – Desktop-Anwendungen auf Touch-Devices laufen zu lassen – gibt es ebenfalls gute Gründe: Es geht nicht darum, dass man diese Software auf dem Device laufen lassen will – dafür wird sie nie optimal geeignet sein – sondern darum, dass man es eben manchmal muss.

Es gibt sehr viel Software die man – aus unterschiedlichen Gründen – niemals als App bekommen wird. Ob das Individualsoftware im Unternehmen ist, Photoshop für den Hobby-Fotographen oder Visual Studio für den Entwickler. Dazu noch der Zoo an USB-Geräten, insbesondere wenn sie Treiber mitbringen oder Software voraussetzen, die man sonst nicht einsetzen könnte.

Die Möglichkeit, diese Software auf dem Tablet laufen zu lassen, entscheidet vielleicht einmal darüber, welches Device ich mit mir herumtrage. 

 

Alles in allem…

Verkürzt ausgedrückt fängt Microsoft mit dem “2 Systeme in einem”-Ansatz die Business-Kunden ein, für die Bestandsschutz und Integration in die Unternehmensinfrastruktur von Bedeutung sind. Und mit dem “Schulen” der Anwender sichern sie ihre Zukunft im Endkunden-Markt.

Wenn man sich diese Motivationslage klar macht, dann machen auch viele sonst eher unverständliche Dinge plötzlich Sinn. Und wenn Microsoft auch morgen noch gute Geschäfte machen will, haben sie meines Erachtens genau den richtigen Weg eingeschlagen – womöglich den einzigen Weg, wenn sie nicht irgendwann das Schicksal anderer ehemaliger Marktführer teilen wollen, die heute keine Bedeutung mehr haben.

 

Diese Betrachtung ist für mich als Anwender nicht gerade konziliant, und sie lässt Microsoft auch nicht unbedingt sympathisch erscheinen. Aber letztlich handeln auch Apple, Google und alle anderen Anbieter nicht anders.

Und selbst wenn Microsoft das letztendlich aus Eigennutz tut – am Ende des Tages verdient auch Microsoft sein Geld damit, mir einen Mehrwert zu bieten. Und unter dem Strich tun sie das mit Windows 8.

Man könnte also durchaus sagen, dass Windows 8 Vorteile für alle Beteiligten – Microsoft, die Hard- und Software-Industrie, und den Anwender – bietet. Jetzt muss Microsoft das nur noch so verkaufen, statt sinnlos Teenies mit dem Surface tanzen zu lassen… .


PS: Das alles ist natürlich nur meine ganz persönliche Interpretation der Dinge…

Share |

Die zwei Gesichter von Windows 8: Schlechtes Marketing und Unverständnis 17.05.2013

Alexander Jung
Alexander Jung, Chief eXpert

Schon wieder: Eine Usability-Studie zu Windows 8. Ergebnis wie erwartet: Metro ist neu und in Teilen nicht tauglich für den Desktop, dazu kommen die Anwender damit nicht automatisch zurecht, wenn es eben kein Desktop-Mode ist.

 

Das Kommentieren des Ergebnisses kann ich mir auch sparen, das hat Georg schon getan:

“Die Erkenntnis aus der Studie ist allerdings schon länger bekannt: Es gibt ein paar Dinge, die der Benutzer wissen muss, weil sie “neu” sind. Durch die Bank hatten die Tester Probleme, die mit diesem Artikel abgedeckt wären (Klassiker: “Runterfahren” bzw. generell das Konzept der Apps).

Mehr gibt es dazu eigentlich nicht zu sagen, die “Schulung” für den Benutzer ist erfahrungsgemäß (!) in 5 MINUTEN erledigt – da ist das wichtigste gesagt, gezeigt und erlernt. Dann klappt es auch mit der Bedienung wieder.”

http://www.windowsblog.at/post/2013/05/01/Windows-8-Usability-Studie.aspx

Was mich eher irritiert ist das Unverständnis dessen, was die zwei Gesichter eigentlich bedeuten…

 

Man merkt es auch der Studie an: Da werden Leute an den normalen Desktop-Rechner gesetzt um sich mit dem alten und neuen UI auseinanderzusetzen. Und selbst die Autoren finden an diesen zwei Welten nichts befremdliches, sondern denken, das müsse so sein:

“Das Kachel-Design hat einen großen Wiedererkennungswert. Microsoft setzt es nicht nur bei dem neuen Betriebssystem für Desktop-PCs und Laptops ein, sondern auch im mobilen Bereich: Die Bedienung der Windows Phones und Tablets erfolgt ebenfalls über die Kacheln.”

Klingt als wäre Windows 8 das Betriebssystem für Desktops und Laptops. Und auf Phones und Tablets wird das gleiche Design (nicht etwa Betriebssystem!) verwendet.

 

Weiter wird zwar bemerkt, dass das tatsächlich zwei Welten sind:

“Da die klassische Desktop-Ansicht unter Windows 8 weiterhin existiert […] , vereint das neue Betriebssystem nun also zwei verschiedene User Interfaces. Diese unterscheiden sich optisch deutlich voneinander und weisen zum Teil auch andere Funktionalitäten auf.”

Um dann wird zu verallgemeinern und den Desktop zu ignorieren:

“Weiterhin zeichnet sich Windows 8 durch viele große Bilder aus, welche mit wenig Text bzw. Schrift kombiniert werden […]. Alle Programme starten grundsätzlich in der Vollbildansicht.”

 

Und natürlich ist den Probanden – es wurden ausdrücklich Leute gewählt, die Windows 8 noch nicht kannten – der Unterschied zwar „offensichtlich“ (im Wortsinn), aber eben nicht in letzter Konsequenz bewusst:

“Alle Testteilnehmer kritisierten, dass die aus früheren Betriebssystemen von Windows erlernten Funktionen „Fenster minimieren“, „Fenster verkleinern“ und „Fenster schließen“ […] bei Windows 8 nicht mehr angezeigt werden […].”

Wieder die Verallgemeinerung „Windows 8“, wieder die Verkennung der Tatsache, dass es sich um zwei getrennte UIs handelt.

 

Meines Erachtens zeigt die Studie zweierlei Dinge:

Erstens, dass es eben nicht damit getan ist, sich an den Windows 8-Rechner zu setzen und einfach loszulegen. Wie es Georg oben schon gesagt hat, muss man sich mit dem neuen UI zumindest 5 Minuten auseinandersetzen.

Nur: Was bei ihm nach „RTFM!“ klingt (also in der Schuld des Nutzers liegt), kann man aber sehr wohl Microsoft in Rechnung stellen. Wenn man dem Anwender ein neues System gibt – so durchdacht es auch sein mag – muss man ihn mitnehmen. Ein kurzes Video nach der Betriebssystem-Installation ist dafür etwas dünn und auf die Hilfe zu verweisen, die ausgerechnet auf dem Start-Screen nicht funktioniert, hilft auch nicht weiter. Ein klar erkennbares Hilfe-Symbol auf der Startseite, der Startbutton zumindest sichtbar, so dass man ihn anklicken kann (selbst wenn damit auf den Startschirm umgeschaltet wird) – oder meinetwegen die Wiederauferstehung von Karl Klammer – damit hätte man den Anwender an die Hand genommen und ihn in die neue Welt eingeführt.

Zweitens zeigt sich hier meines Erachtens, dass auch die Autoren der Studie selbst nicht wirklich durchschaut haben, was es mit Windows 8 und seinen zwei Gesichtern eigentlich auf sich hat.

Dazu mehr im nächsten Beitrag…

Share |

Eigenarten der Programmiersprachen ;-) 16.05.2013

Saša Endler
Saša Endler, Senior eXpert
Jede Programmiersprache hat so ihre Tücken und Eigenarten. Neben dem Wissen, dass es sie gibt und wie man mit ihnen umgeht, sollte man aber auch den Spaßfaktor, den sie bereitstellen nicht außer Acht lassen.

Gerade diesen Aspekt zeigt Gary Bernhardt sehr eindrucksvoll im unten gezeigten Video.
Share |

Das Weak Event Pattern in .NET 4.5 13.05.2013

Max Jäger
Max Jäger,
Senior eXpert
Bei der Verwendung von Events in .Net gibt es zwei beteiligte Parteien: das Objekt, das das Event auslöst (Sender), und das Objekt, das auf das ausgelöste Event reagiert (Empfänger). Bei der Zuweisung des Eventhandlers an das Event in der Form
SenderObjekt.Event += EmpfaengerObjekt.Handler
wird eine sogenannte strong reference zwischen Sender und Empfänger erzeugt. Durch diese Beziehung wird die Lebensdauer des Empfänger-Objektes durch die Lebensdauer des Sender-Objektes beeinflusst (sofern der Eventhandler nicht explizit entfernt wird) – was nicht immer gewünscht ist und auch zu Memory Leaks führen kann: das Empfänger-Objekt bleibt am Leben, obwohl dies nicht beabsichtigt ist.
Eine mögliche Lösung hierfür ist das Weak Event Pattern, das ich in diesem Artikel näher vorstellen und besonders auf die neuen Möglichkeiten unter .NET 4.5 eingehen möchte.

Ausgangssituation

Zur Verdeutlichung des angesprochenen Verhaltens dient das folgende Beispiel. Es wird die Beziehung zwischen einer Verwaltung von Arbeitszeiten und mehreren Ansichten (z. B. Wochenansicht, Tagesansicht etc.) dargestellt. Wir haben eine TimeEntryCollection, in der die Zeiteinträge verwaltet werden. Wird ein neuer Zeiteintrag hinzugefügt, so wird das Event TimeEntryAdded ausgelöst, das alle Ansichten über den neuen Zeiteintrag benachrichtigt.

   1: public class TimeEntryCollection
   2: {
   3:     public event EventHandler<TimeEntryEventArgs> TimeEntryAdded;
   4:  
   5:     List<TimeEntry> timeEntries = new List<TimeEntry>();
   6:  
   7:     public void AddTimeEntry(DateTime start, DateTime end, string description, string user)
   8:     {
   9:         var entry = new TimeEntry(start, end, description, user);
  10:  
  11:         this.timeEntries.Add(entry);
  12:         OnNewTimeEntryAdded(entry);
  13:     }
  14:  
  15:     private void OnNewTimeEntryAdded(TimeEntry entry)
  16:     {
  17:         if (TimeEntryAdded != null)
  18:         {
  19:             TimeEntryAdded(this, new TimeEntryEventArgs(entry));
  20:         }
  21:     }
  22: }

Die TimeEntryEventArgs, die dem Event mitgegeben werden, beinhalten in meinem Beispiel den Zeiteintrag selbst und den Zeitpunkt, an dem das Event ausgelöst wurde.

   1: public class TimeEntryEventArgs : EventArgs
   2: {
   3:     public TimeEntry TimeEntry { get; private set; }
   4:     public DateTime TimeStamp { get; private set; }
   5:  
   6:     public TimeEntryEventArgs(TimeEntry entry)
   7:     {
   8:         this.TimeEntry = entry;
   9:         this.TimeStamp = DateTime.Now;
  10:     }
  11: }

Für die Empfänger-Objekte gibt es eine WeekView- und eine DayView-Klasse, die bei hinzugefügten Zeiteinträgen benachrichtigt werden. Diese beiden Klassen stellen verschiedene Ansichten dar – eine Wochenansicht und eine Tagesansicht. In diesen Klassen wird nur über die Konsole ausgegeben, dass die entsprechende Ansicht über den neuen Zeiteintrag informiert wurde. Um das Beispiel kompakt zu halten, wird hier auf die Verwendung eines Interfaces verzichtet und die gleiche Methode doppelt implementiert.

   1: public class WeekView
   2: {
   3:     public void TimeEntryAdded(object sender, TimeEntryEventArgs e)
   4:     {
   5:         // hier könnten Berechnungen für die Wochenarbeitszeit durchgeführt werden
   6:         Console.WriteLine(
   7:             string.Format("Wochenansicht:\nZeit: {0} - {1}\nBeschreibung: {2}\nBenutzer: {3}\n",
   8:                 e.TimeEntry.Start,
   9:                 e.TimeEntry.End,
  10:                 e.TimeEntry.Description,
  11:                 e.TimeEntry.User));
  12:     }
  13: }
   1: public class DayView
   2: {
   3:     public void TimeEntryAdded(object sender, TimeEntryEventArgs e)
   4:     {
   5:         // hier könnten Berechnungen für die Tagesarbeitszeit durchgeführt werden
   6:         Console.WriteLine(
   7:             string.Format("Tagesansicht:\nZeit: {0} - {1}\nBeschreibung: {2}\nBenutzer: {3}\n",
   8:                 e.TimeEntry.Start,
   9:                 e.TimeEntry.End,
  10:                 e.TimeEntry.Description,
  11:                 e.TimeEntry.User));
  12:     }
  13: }

Das Programm selbst hält eine TimeEntryCollection, erzeugt die zwei Ansichten-Objekte und fügt mehrere Zeiteinträge in die Liste ein. Vor dem Einfügen des letzten Eintrages wird jedoch die Tagesansicht auf null gesetzt – in einem realen Szenario vielleicht aufgrund eines Wechsels der Ansicht.

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         TimeEntryCollection timeEntries = new TimeEntryCollection();
   6:  
   7:         WeekView weekView = new WeekView();
   8:         timeEntries.TimeEntryAdded += weekView.TimeEntryAdded;
   9:  
  10:         timeEntries.AddTimeEntry(DateTime.Parse("08.03.2013 08:00"), DateTime.Parse("08.03.2013 16:30"), "Office Day", "Max");
  11:  
  12:         DayView dayView = new DayView();
  13:         timeEntries.TimeEntryAdded += dayView.TimeEntryAdded;
  14:  
  15:         timeEntries.AddTimeEntry(DateTime.Parse("28.02.2013 08:00"), DateTime.Parse("28.02.2013 18:30"), "Basta 2013", "Max");
  16:  
  17:         Console.WriteLine("Tagesansicht auf NULL setzen.\n");
  18:         dayView = null;
  19:         timeEntries.AddTimeEntry(DateTime.Parse("27.02.2013 09:00"), DateTime.Parse("27.02.2013 10:30"), "Meeting", "Max");
  20:         System.GC.Collect();
  21:         Console.WriteLine("Garbage Collector hat aufgeräumt.\n");
  22:  
  23:         timeEntries.AddTimeEntry(DateTime.Parse("08.02.2013 08:00"), DateTime.Parse("08.02.2013 18:30"), "Kick-Off 2013", "Max");
  24:  
  25:         Console.ReadLine();
  26:     }
  27: }

Die Eventhandler werden auf die bekannte Art und Weise zugewiesen. Um sicherzustellen, dass nicht mehr benötigte Objekte durch den Garbage Collector aufgeräumt werden, wird dieser hier explizit aufgerufen. Das gezeigte Programm erzeugt folgende Ausgabe auf der Konsole:

image

Wie zu sehen ist, wird auch die Tagesansicht sowohl über den Zeiteintrag für den Kick-Off als auch das Meeting benachrichtigt, obwohl die Referenz vorher auf null gesetzt wurde und der Garbage Collector gelaufen ist – das Objekt bleibt also durch den hinzugefügten Eventhandler am Leben. Die einfachste Variante, die Beziehung zwischen Sender und Empfänger aufzulösen, ist sicherlich das Deregistrieren des Eventhandlers:
Fügen wir die folgende Zeile vor der Stelle ein, an der die Referenz auf null gesetzt wird, so wird auch der Eventhandler nicht mehr aufgerufen:

timeEntries.TimeEntryAdded –= dayView.TimeEntryAdded;

image

Doch wie bereits gesagt, ist dies nicht immer möglich (z. B. bei der Programmierung von eigenen Controls, die von anderen verwendet werden) – und dann kommt das Weak Event Pattern ins Spiel.

Das Weak Event Pattern – bisherige Vorgehensweise

Das Weak Event Pattern an sich existiert bereits seit .NET 3.0. Es wurde entworfen, um eine lose Kopplung zwischen Sender und Empfänger zu ermöglichen, sodass sich ein Empfänger an das Event eines Senders hängen kann, die Lebenszeit des Empfängers aber nicht durch die Lebenszeit des Senders bestimmt wird. Diese lose Kopplung zwischen den beiden Objekten wird als weak reference bezeichnet – daher auch der Name Weak Event Pattern.

Bis .NET 4.5 war die Implementierung des Weak Event Patterns eher aufwendig. Zunächst musste eine Manager-Klasse von WeakEventManager abgeleitet werden (normalerweise für jedes Event eine eigene Manager-Klasse). Die Klasse, die auf das Event reagieren wollte, musste dann das IWeakEventListener-Interface und dadurch die ReceiveWeakEvent-Methode implementieren. Die Verbindung zwischen Sender und Empfänger musste dann über die AddListener-Methode des Managers erfolgen. Und das alles nur, um die enge Kopplung zwischen Sender und Empfänger zu lösen. Schon aufwendig, oder?

Und so geht’s in .NET 4.5

Das dachte man sich anscheinend auch im Hause Microsoft, und hat mit .NET 4.5 eine generische Version des WeakEventManagers eingeführt (die bisherige Variante bleibt aber weiterhin als Möglichkeit bestehen). Die Klassen TimeEntryCollection, TimeEntry, TimeEntryEventArgs, DayView und WeekView müssen nicht geändert werden – und wir brauchen auch keinen eigenen WeakEventManager, denn es gibt nun einen generischen WeakEventManager mit folgende Signatur:

WeakEventManager<TEventSource, TEventArgs>

TEventSource ist der Typ des Senders, TEventArgs der Typ der Argumente des Events. Auf diesem Manager gibt es eine AddHandler-Methode mit folgender Signatur:

public static void AddHandler(
    TEventSource source,
    string eventName,
    EventHandler<TEventArgs> handler
)

Source ist das Sender-Objekt, eventName der Name des Events als String und handler die Eventhandler-Methode. Um diesen WeakEventManager zu verwenden, müssen wir nun lediglich das Setzen des Eventhandlers über eben diese AddHandler-Methode durchführen.
Somit sieht unser Programm nun folgendermaßen aus:

   1: class Program
   2: {
   3:     static void Main(string[] args)
   4:     {
   5:         TimeEntryCollection timeEntries = new TimeEntryCollection();
   6:  
   7:         WeekView weekView = new WeekView();
   8:         // Verknüpfen des Events mit dem Handler nun über den WeakEventManager
   9:         //timeEntries.TimeEntryAdded += weekView.TimeEntryAdded;
  10:         WeakEventManager<TimeEntryCollection, TimeEntryEventArgs>.AddHandler(timeEntries, "TimeEntryAdded", weekView.TimeEntryAdded);
  11:  
  12:         timeEntries.AddTimeEntry(DateTime.Parse("08.03.2013 08:00"), DateTime.Parse("08.03.2013 16:30"), "Office Day", "Max");
  13:  
  14:         DayView dayView = new DayView();
  15:         // Verknüpfen des Events mit dem Handler nun über den WeakEventManager
  16:         //timeEntries.TimeEntryAdded += dayView.TimeEntryAdded;
  17:         WeakEventManager<TimeEntryCollection, TimeEntryEventArgs>.AddHandler(timeEntries, "TimeEntryAdded", dayView.TimeEntryAdded);
  18:  
  19:         timeEntries.AddTimeEntry(DateTime.Parse("28.02.2013 08:00"), DateTime.Parse("28.02.2013 18:30"), "Basta 2013", "Max");
  20:         // Eventhandler wird nicht deregistriert
  21:         //timeEntries.TimeEntryAdded -= dayView.TimeEntryAdded;
  22:  
  23:         Console.WriteLine("Tagesansicht auf NULL setzen.\n");
  24:         dayView = null;
  25:  
  26:         timeEntries.AddTimeEntry(DateTime.Parse("27.02.2013 09:00"), DateTime.Parse("27.02.2013 10:30"), "Meeting", "Max");
  27:         System.GC.Collect();
  28:         Console.WriteLine("Garbage Collector hat aufgeräumt.\n");
  29:  
  30:         timeEntries.AddTimeEntry(DateTime.Parse("08.02.2013 08:00"), DateTime.Parse("08.02.2013 18:30"), "Kick-Off 2013", "Max");
  31:  
  32:         Console.ReadLine();
  33:     }
  34: }

Und das kommt in der Kommandozeile an:

image

Die Ausgabe zeigt, dass nun der Zeiteintrag für den Kick-Off nicht mehr in der Tagesansicht erscheint – denn diese gibt’s ja nicht mehr. Aber auch hier wurde explizit der Garbage Collector aufgerufen. Der Eintrag für das Meeting wurde vor dem Aufruf des Garbage Collectors eingefügt und somit wurde auch die Tagesansicht noch benachrichtigt. Dies gilt es in der Praxis zu berücksichtigen, denn der Eventhandler wird trotzdem aufgerufen, wenn der Garbage Collector noch nicht aufgeräumt hatte.

Fazit

Mit .NET 4.5 wurde die Verwendung des Weak Event Patterns deutlich vereinfacht, und macht es somit auch attraktiver, benutzt zu werden. Die generische Variante ist nicht ganz so effizient wie eine speziell abgeleitete Variante, es ist aber deutlich weniger Code erforderlich. Sollte die Performance also nicht an erster Stelle stehen, so ist die neue generische Variante eine gute und einfache Möglichkeit, das Weak Event Pattern einzusetzen.

Wichtig: das Weak Event Pattern verhindert nicht, dass unnütze Events behandelt werden. Es verhindert lediglich, dass Objekte durch Event-Registrierungen am Leben erhalten werden, obwohl dies nicht notwendig ist.

Wer sich umfassender informieren möchte, dem seien folgende Seiten empfohlen:

Share |