Heute war es endlich so weit.
Seit gerade eben bin ich Besitzer dieses schicken Pakets.
(Ja die Bilder sind nicht gerader der Hammer)

schauen wir doch einmal nach, was sich in diesem Paket befindet
Paketinhalt
- Nokia Lumia 800
- Schutzhülle (um das neue Spielzeug zu schützen)
- Anleitung + Kurzanleitung (Kram halt, wer schaut da schon rein)
- Headset
- Ladeeinheit (Stecker + USB Kabel)

Am 8 & 9 September öffnet die Börse in Wuppertal,
Ihre Pforten für die diesjährige
NRW Conf.
Auch dieses Mal, erwartet euch wieder ein Randvollgepacktes Programm
nur ein kleiner Auszug:
ASP.NET MVC Rock ‘n’ Roll mit Daniel Fischer
Microsoft alternative Web-Plattform zu den *klassischen* Web Forms bietet eine Umgebung in der es möglich ist saubere Architekturen und cleanen Code mit einander zu verbinden. Dabei kann man eine Entwicklungsgeschwindigkeit aufbauen, die sich nicht hinter RAD-Tools wie z.B. Lightswitch verstecken muss. Daniel Fisher zeigt in diesem Vortrag Code und Vorgehensweisen aus Projekten. Nützliche Tipps für den Web-Entwicklungsalltag inklusive!
10 spannende Sachen, die man mit SQL Server CLR Integration machen kann mit Thorsten Kansy
Sicherlich haben Sie schon von der CLR Integration gehört mit C#/ VB.NET interessante und mächtige Funktionalitäten programmiert werden können. Diese Session stellt zehn Möglichkeiten vor und zeigt, wie sie umgesetzt wurden. Darunter unter anderem das Abfragen von Wechselkursen der EZB, die Erstellung und der anschließende Email-Versand von Berichten (PDF), das Aufspüren von Dubletten, usw.
Mit Git beginnen mit Alex Gross
Git ist ein fortschrittliches und äußerst flexibles Tool zur Verwaltung von Quellcode. Alexander Groß zeigt wärend dieser Session alles was sie für den Einstieg benötigen: Über den grundlegenden Einsatz von Git-Befehlen, über die Arbeit mit Entwicklungszweigen (Branches) bis hin zu Tools für die Kommandozeile, für Visual Studio und zum Lösen von Merge-Konflikten.
der komplette Session Katalog ist unter Sessions zu erreichen
wer am 9.9 noch nichts zu tun hat und auch noch zufällig in der nähe von Wuppertal sein Unwesen treibt,
dem kann ich nur eins Empfehlen:
Meldet euch an solange es noch Karten gibt
Was Ihr für diesen Preis in Wuppertal geboten bekommt, ist einfach unbezahlbar.
So auch von mir alles gute, zu deinem 5 Geburtstag.
Während dieser 5 Jahre hast Du schon einiges gelernt und deinem Vater oder so manch einem Gewinner der 7 Gewinnspielen, so manche Freude bereitet. Ok es waren auch schwierige Zeiten dabei aber darüber spricht man ja nicht. Im deinem letzten Kindergarten Jahr, wird noch so einiges passieren aber so wie dein bisheriges Leben gemeistert hast wirst du das auf jeden Fall auch schaffen.
@Jan so langsam musst Du als stolzer Papa, Dir darüber Gedanken machen, in welche Grundschule Du dein Kind einschulen möchtest.
unter Windows Azure veranstaltet Microsoft, nun schon zum dritten mal ein Gewinnspiel.
was gibt es zu Gewinnen?
5 x ein aktuelles Windows Phone 7 Smartphone
5 x Xbox 360 mit Kinect und Kinect Adventures
10 x Visual Studio 2010 Professional
wie man sehen kann, die ca 5 – 10 Minuten Arbeit können sich lohnen.
Neulich hatte ich während der Implementations- Phase eines ASP.Net MVC 2 Projektes, ein kleines Problem.
Ich wollte eine HTML Tabelle, in welche man mit Hilfe dieser Tabelle auch neue Daten hinzufügen kann und diese im Anschluss zu speichern.

Das Dynamische hinzufügen, war mittels JQuery selbstverständlich sehr schnell realisiert.
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<MvcApplication10.Models.Kunde>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Startseite
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% if (Model.Count > 0) %>
<% { %>
<table id="templateTableRow" style="display:none">
<tr>
<td><%: Html.TextBox("Name")%></td>
<td><%: Html.TextBox("Vorname")%></td>
<td><%: Html.TextBox("Strasse")%></td>
<td><%: Html.TextBox("Hausnummer")%></td>
</tr>
</table>
<%using (Html.BeginForm()) %>
<% { %>
<table id="tbl">
<tr>
<th><%: Html.LabelFor(m => Model[0].Name) %></th>
<th><%: Html.LabelFor(m => Model[0].Vorname) %></th>
<th><%: Html.LabelFor(m => Model[0].Strasse) %></th>
<th><%: Html.LabelFor(m => Model[0].Hausnummer) %></th>
</tr>
<% foreach(var item in Model) %>
<% { %>
<tr>
<td><%: item.Name %></td>
<td><%: item.Vorname %></td>
<td><%: item.Strasse %></td>
<td><%: item.Hausnummer%></td>
</tr>
<% } %>
</table>
<input type="submit" value="save" />
<% } %>
<% } %>
<input type="button" value="Add" onclick="BLOCKED SCRIPT$('#tbl').append($('#templateTableRow').html())" />
</asp:Content>
public ActionResult Index()
{
List<Kunde> kunden = new List<Kunde>();
kunden.Add(new Kunde { Name = "Schmitt", Vorname="Lars", Strasse="...", Hausnummer="..."});
kunden.Add(new Kunde { Name = "...", Vorname="Walter", Strasse="...", Hausnummer="..."});
return View(kunden);
}
Fein, das war ja einfach, jedoch der Schrecken folgt auf dem Fuße, denn nachdem ein paar neue Testdaten erfasst und das Formular abgeschickt wurde.
Gelangten die eingegebenen Daten, nicht in die dafür vorgesehene Generischen Liste vom Typ Kunde.

Um diesem Fehler auf die Spur zu kommen, könnte man sich z.B. die übergebenen Daten anschauen.
Warum wird mit dieser Daten das Model nicht gefüllt?
Hintergrund:
Die Daten die von einer Webseite, an die Controller Methode übergeben werden, werden erst durch einen so genannten ModelBinder, den einzelnen Parameter zugewiesen.
Zwar hat MS uns einen Default ModelBinder spendiert, jedoch kann dieser logischerweise auch nicht alle Fälle abdecken.
Da man jetzt gesehen hat, wie die Daten übergeben werden, könnte man auf die Idee kommen, ein neues Model zu erstellen welches die übergebenen Daten aufnehmen kann.
public class Kunde
{
public string[] Name { get; set; }
public string[] Vorname { get; set; }
public string[] Strasse { get; set; }
public string[] Hausnummer { get; set; }
} Jedoch wäre dieses der Falsche Weg!
Einige Suchanfragen später … Ein eigener ModelBinder muss her.
Um einen eigenen ModelBinder zu erstellen, muss nur das Interface IModelBinder aus dem Namensraum System.Net.MVC Implementiert werden.
public class KundenListModelBinder : IModelBinder
{
#region IModelBinder Member
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
List<Kunde> kunden = new List<Kunde>();
NameValueCollection col = controllerContext.HttpContext.Request.Form;
var namen = col["Name"].Split(',');
var vornamen = col["Vorname"].Split(',');
var strassen = col["Strasse"].Split(',');
var hausnummern = col["Hausnummer"].Split(',');
Kunde kunde = null;
for (int i = 0; i < kunden.Count; i++)
{
kunde = new Kunde();
kunde.Name = namen<img src="http://dotnet-forum.de/emoticons/emotion-55.gif" alt="Idea" />;
kunde.Vorname = vornamen<img src="http://dotnet-forum.de/emoticons/emotion-55.gif" alt="Idea" />;
kunde.Strasse = strassen<img src="http://dotnet-forum.de/emoticons/emotion-55.gif" alt="Idea" />;
kunde.Hausnummer = hausnummern<img src="http://dotnet-forum.de/emoticons/emotion-55.gif" alt="Idea" />;
kunden.Add(kunde);
}
return kunden;
}
#endregion
}
Um diesen ModelBinder, nun auch benutzen zu können, muss er nur noch dem MVC Framework bekannt gemacht werden.
Wie so oft, gibt es nicht nur einen Weg dieses zu bewerkstelligen.
1. Die Globale Methode
Der ModelBinder kann, innerhalb der Global.asax dem Framework bekanntgemacht werden.
protected void Application_Start()
{
ModelBinders.Binders[typeof(List<Kunde>)] = new KundenListModelBinder();
}
2. Die Lokale Methode (von mir bevorzugt)
Der Modelbinder kann aber auch immer nur da, wo er auch wirklich benötigt wird angegeben werden.
public ActionResult Index([ModelBinder(typeof(KundenListModelBinder))] List<Kunde> kunden)
{
return View(kunden);
}
abschließend natürlich der Beweis, dass es auch wirklich klappt

Im Laufe des heutigen Tages, (update seid 19:00 MEZ) steht für alle MSDN Abonnenten, das erste Service Pack,
für die von uns so geliebte Entwicklungsumgebung zur Verfügung.
Link Download: MSDN
Was wurde geändert: Änderungen
ab dem 10 März sollten dann auch, alle anderen das Update durchführen können.
Viele von euch werden, an dieser Stelle diesmal nichts neues Lernen, doch leider musste ich erst heute wieder feststellen, dass selbst solche Grundlagen nicht jedem bekannt sind.
Im großen und ganzen, existieren 3 unterschiedliche Möglichkeiten ein Objekt zu Instanziieren. Wenn man diese verschiedenen Pattern mit bedacht einsetzt, kann eine Anwendung einiges an Geschwindigkeit zulegen. Denn machen wir uns nichts vor, egal wie gut die Anwendung ist, ein Benutzer wird manche Funktionen im Lebenszyklus eines Programmes nur sehr selten benutzen.
Anhand von einigen kurzen sehr stark vereinfachten Beispielen, möchte ich euch heute diese 3 Möglichkeiten vorstellen.
- Lazy Loading (träges Laden)
- Eager Loding (eifriges Laden)
- Over-Eager Loading (über eifriges Laden)
Stellen wir uns vor, wir haben eine Anwendung mit einigen Objekten. Wenn wir jetzt alle Objekte beim Starten der Anwendung Instanziieren würden, dann würde der Startvorgang der Anwendung im Verhältnis gesehen, einfach viel zu lange dauern. Genau an dieser Stelle könnte uns dieses Pattern helfen.
Lazy Loading:
Ein Objekt wird nicht im Cache vorgehalten und erst zu dem Zeitpunkt wo dieses Objekt benötigt wird wird es Instanziiert.
public class Orders
{
public int OrderID { get; set; }
private List<Detail> _orderDetails;
public List<Detail> OrderDetails
{
get
{
return _orderDetails ?? LoadDetailsForOrderID(orderID: OrderID);
}
}
//irgendwo im Programm dann der Zugriff auf die Details
public void GetOrder(int orderID)
{
Orders order = GetOrder(id: orderID);
//erst jetzt werden die OrderDetails initialisiert
order.OrderDetails.ForEach( ... );
}
} oder auch mittels des neuen Objektes Lazy<T> (.Net Framework 4)
public class Orders
{
public int OrderID { get; set; }
public Lazy<List<Detail>> OrderDetails {get;set;}
//irgendwo im Programm dann der Zugriff auf die Details
public void GetOrder(int orderID)
{
Orders order = GetOrder(id: orderID);
//erst jetzt werden die OrderDetails initialisiert
order.OrderDetails.Value.ForEach((item) => item.ToString());
}
}
Verständlicherweise ergeben sich in unserer Anwendung, auch immer wieder verschiedene Situationen wo man als Entwickler sagen kann, wenn ein User dieses Objekt benutzt, wird er mit hoher Wahrscheinlichkeit auch ein anderes weiteres Objekt benötigen. Also können wir das schon einmal mittels der Eager Loading Instanziieren. Ich bekomme also ein Vollständiges Objekt und kann damit sofort Arbeiten.
Eager Loding:
public class Orders
{
public Orders(int orderID)
{
_orderDetails = LoadDetailsForOrderID(orderID: orderID);
}
public int OrderID { get; set; }
private List<Detail> _orderDetails;
public List<Detail> OrderDetails
{
get
{
return _orderDetails;
}
}
//irgendwo im Programm dann der Zugriff auf die Details
public void GetOrder(int orderID)
{
Orders order = GetOrder(id: orderID);
//das Object ist schon lange vorhanden, denn die Instanziierung wurde im Konstruktor vorgenommen
order.OrderDetails.ForEach( ... );
}
}
Over-Eager Loding:
Im Prinzip kann man dieses Pattern als eine Mischung aus den anderen beiden Sehen. Es wird erst einmal das Grundobjekt erzeugt, und zurückgegeben. Der Anwender kann also sofort mit der Order Arbeiten, sollte er sich irgendwann entschließen auf die Details zuzugreifen bekommt er diese, zumindest schon mal schneller als beim Eager Loading bestenfalls natürlich sofort.
Wie Funktioniert das ganze:
Das Geheimnis liegt in der Implementation, es wird zb durch die Instanziierung ein Hintergrundprozess angestoßen, der die OrderDetails beschafft.
public class Orders
{
public Orders(int orderID)
{
Task.Factory.StartNew(() =>
{
_orderDetails = LoadDetailsForOrderID(orderID: orderID);
}
}
public int OrderID { get; set; }
private List<Detail> _orderDetails;
public List<Detail> OrderDetails
{
get
{
return _orderDetails;
}
}
//irgendwo im Programm dann der Zugriff auf die Details
public void GetOrder(int orderID)
{
Orders order = GetOrder(id: orderID);
//ob das Object schon vorhanden ist, weiß man nicht
order.OrderDetails.ForEach( ... );
}
} So sollte das natürlich nicht sein, denn sobald Threads oder Tasks mit ins Spiel kommen, darf man natürlich nicht auf ein anständiges Locking verzichten.
Fazit: Abschließend kann ich euch leider keine Empfehlung geben wie Ihr es am besten machen könnt, das hängt leider immer von der jeweiligen Domäne ab ich kann euch nur raten, nutzt und Experimentiert mit diesen Möglichkeiten, um für euch die passende Vorgehensweise zu entdecken.
Aus der Rubrik: Neues von der Basta heute meine zweite Session C# Phase 4 mit Christian Nagel
Seit C# 4.0 unterstützt unsere geliebte Entwicklungssprache, diese recht interessante Feature. In diesem Blog Post, möchte ich diese für C# Entwickler neue Möglichkeit, einmal etwas genauer betrachten.
Obwohl die optionalen Parameter ganz klar sehr nützlich sein können, so bergen Sie auch einige Gefahren die man beachten sollte , aber fangen wir erst einmal langsam an.
Optionale Parameter was ist das eigentlich?
Manche Entwickler unter euch, werden es schon z.B. aus der VB Zeit heraus kennen.
Ihr kennt das doch, Ihr schreibt eine Methode mit sagen wir mal 5 Parameter, jedoch Ihr braucht nicht immer alle Parameter. wie in diesem Beispiel
public string BuildSQL(string table) { return BuildSQL(table, "*"); }
public string BuildSQL(string table, string columns) { return BuildSQL(table, columns, ""); }
public string BuildSQL(string table, string columns, string wherePart) { return BuildSQL(table, columns, wherePart, ""); }
public string BuildSQL(string table, string columns, string wherePart, string orderBy) { return BuildSQL(table, columns, wherePart, orderBy, ""); }
public string BuildSQL(string table, string columns, string wherePart, string orderBy, string limit)
{
return String.Format("SELCT {0} FROM ...)", columns);
} allein um die einfachen Fälle abzudecken, bräuchtet Ihr 4 weitere Methoden für die Parameterüberladung, von den Fällen wie z.B. Tabelle und Order By mal abgesehen.
Wollen wir das? Nein, darum das ganze nochmal
public string BuildSQL(string table, string columns="*", string wherePart="", string orderBy="", string limit=""){ … }
BuildSQL("User");
BuildSQL("User", "Name");
BuildSQL("User", limit: "10");
BuildSQL("User", orderBy:"Name", limit:"20", columns:"Name"); Mit Hilfe der optionalen Parameter, brauchen wir jetzt nur noch eine Methode um das Ganze zu bewerkstelligen.
Wichtig Parameter die optional sein sollen, müssen unbedingt am Ende der Parameterliste stehen. Zusätzlich können wir in diesem Beispiel eine weitere Neuerung sehen.
Die benannten Parameter, helfen uns nicht nur beim Aufruf auf manche Parameter zu verzichten, sondern gibt es uns auch eine neue Art der Übersicht, so dass man sobald man sich den Aufruf anschaut, auf den ersten Blick sofort erkennen kann, welcher Wert in welchen Übergabe Parameter übergeben wird (natürlich nur solange eure Parameter eine sprechende Bezeichnung haben)
Was euch in diesem Beispiel ebenfalls auffallen sollte ist, dass die Reihenfolge wie man die Parameter angibt ist eigentlich nicht nur nicht relevant ist, sondern das die Reihenfolge wie man die Parameter angibt sogar beachtet wird.
static void Main(string[] args)
{
var p = new Program();
int n = 3;
p.WriteSomething(y:n++, x:n);
}
public void WriteSomething(int x, int y)
{
Console.WriteLine("x:{0}, y:{1}", x, y);
Console.ReadLine();
} Die Ausgabe lautet, für manch einen unerwartet
x:4, y:3 wie gesagt die Reihenfolge spielt eine Rolle
- erst wird dem Parameter y der Wert von n also 3 zugewiesen
- dann wird n Inkrementiert
- und erst dann dem x Parameter der inkrementierte Wert 4
An sich also ein schönes Feature, … doch wo liegt denn bei den optionalen Parameter eine Gefahr???
…
Um dieses Problem zu demonstrieren muss ich eine kleine Änderung an dem Projekt vornehmen.
Wir lagern die Methode inkl. der Defaultparameter in eine eigene DLL aus, kompilieren und schauen uns den erzeugten IL-Code an.
Hinweis:
Bisher, habe ich für solche Zwecke immer den Reflector benutzt, doch da Redgate sich dazu entschlossen hat, zukünftig 35 $ für dieses Produkt zu nehmen, gewöhne ich mich jetzt schon an die Alternative
ILSpy. Entwickelt wird dieses Tool von den gleichen Entwicklern die auch die IDE SharpDevelop hervorgebracht haben.
Dieser kleine Ausschnitt, zeigt uns nun den erzeugten IL-Code der Methode.

Das komische daran ist nur, dass ich an dieser Stelle weder etwas von den optionalen Parametern noch von den Defaultwerten entdecken kann.
(Hmm, was macht der Compiler denn da, oder habe ich die falsche DLL benutzt?)
Nein, die Assembly war auf jeden Fall die richtige
…
schauen wir uns einfach mal, die ausführbare Datei im ILSpy an (in der Hoffnung an das wir an dieser Stelle mehr sehen)
Also ILSpy starten, Exe laden und dann suchen wir mal die Stelle an der die Methode (z.B. BuildSQL) aufgerufen wird

So da haben wir ja zumindest schon einmal drei der Aufrufe
Wenn wir uns jetzt nochmal die C# Varianten in Gedächtnis rufen
//Zeile IL_0008 – IL_0026
BuildSQL("User");
//Zeile IL_0027 – IL_0046
BuildSQL("User", "Name");
//Zeile IL_0047 – IL_0064
BuildSQL("User", limit: "10");
in den Zeilen 8 – 26 erkennen wir, dass obwohl wir in unserm C# Code nur den Wert User an den Parameter table übergeben haben, zeigt der IL-Code das wir der Methode BuildSQL immer 5 Werte übergeben.
in diesem Beispiel können wir auch erkennen, was mit den Default werten passiert, Diese werden wie zb in der Zeile IL_000d bereits übergeben-
Fassen wir diese Erkenntnisse noch einmal kurz zusammen
- das Feature der benannten Parameter erlaubt es uns, Parameter beim Aufruf Namentlich zu benennen
- das Feature optionale Parameter, erlaubt es uns beim Aufruf einer Methode verschiedene Parameter nicht zu versorgen
- Defaultparameter erlauben es die Defaultwerte zu bestimmen, die immer dann benutzt werden wenn wir nichts übergeben
- Wenn man sich den erzeugten IL-Code anschaut, sieht man zumindest bei der Methode BuildSQL keine Veränderung im Gegensatz zu einer ‘normalen’ Methode
Wenn man sich den IL-Code anschaut, erkennt man jedoch, dass diese neuen Möglichkeiten sind nur syntaktischer Zucker sind, denn in Wirklichkeit übergeben wir immer jedem einzelnen Parameter einen Wert
Und genau an dieser Stelle, sieht der ein oder andere auch schon das Problem
Wenn wir nun eine Anwendung entwickeln, die ähnlich der Bespielapplikation aufgebaut ist. (eine ausführbare Datei und eine Assembly)
Hier befindet sich nun eine Methode X mit z.B. folgenden Parametern (string, string, bool=true) wobei der letzte Paramter ein Defaultparameter ist.
Die Applikation befindet sich bei einem Kunden im Einsatz, bis zu dem Tage an dem der Kunde anruft und einen Fehler meldet
Schnell kann man den Fehler in der Methode X ausfindig machen und stellt fest, der Defaultparameter müsste eigentlich false und nicht true sein.
Also ändert man den Defaultparameter und testet die nun veränderte Methode … Da wir Ihr ja nur die Library verändert haben, wird auch nur diese beim Kunden eingespielt
Jedoch beim Kunden ist dieser Fehler nicht verschwunden, … Ihr erinnert euch an diesen Blogeintrag und es fällt euch wieder ein …
Durch das Umsetzten des Defaultparameters, habt Ihr nicht unbedingt die Assembly verändert in der sich eure cs Datei befindet, sondern jedem einzelne Assembly die diese eine Methode aufruft!
Ein weiterer Bericht von der Basta Spring.
Diese Library gibt euch ein Vorgeschmack, auf das was in der nächsten Version des Framework kommen wird.
Die bisherigen Möglichkeiten einen Asyncronen Aufruf durchzuführen, ist mit den heutigen Mitteln zwar nicht besonders schwierig, jedoch schrecken manche Entwickler immer noch davor davor zurück, einen Vorgang asyncron durchzuführen.
Warum sollte ich Vorgänge asyncron durchführen?
Bei einem Vorgang der nur wenige Millisekunden dauert, muss ich den Vorgang nicht zwangsläufig asyncron durchführen, jedoch sobald der Vorgang länger dauert oder nicht abzusehen ist wie lang der jeweilige Vorgang dauern könnte, sollte man es machen.
Den Fakt ist, das User Interface sollte auch während einer länger laufenden Aktion, immer bedienbar bleiben!! den so ein Dialog verstärkt das Vertrauen eines Users nicht wirklich!
Wie funktioniert das ganze
Beispiel ohne Library am Beispiel des WebClient NS: System.Net
static void Main(string[] args)
{
string url = "http://www.Microsoft.de";
var client = new WebClient();
client.DownloadDataCompleted += client_DownloadDataCompleted;
client.DownloadDataAsync(new Uri(url));
//an dieser Stelle sind noch keine daten vorhanden
Console.ReadLine();
Console.WriteLine("<END>");
}
static void client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
//jetzt kommen die Daten
string strData = Encoding.Default.GetString(e.Result);
Console.WriteLine(strData);
}
<pre>
Durch diese paar Zeilen Code würde die UI während des Herunterladen immer zugreifbar bleiben.
Beispiel mit Library
<span class="lnum"></span>
static void Main(string[] args)
{
DownloadData();
//an dieser Stelle sind noch keine daten vorhanden
Console.ReadLine();
Console.WriteLine("<END>");
}
private async static void DownloadData()
{
string url = "http://www.Microsoft.de";
var client = new WebClient();
//Zeile 16
string strData = await client.DownloadDataAsync(new Uri(url));
Console.WriteLine(strData);
}
An diesem Beispiel erkennen wir, das wir durch die beiden neuen Schlüsselwörter
async und Await das gleiche Ergebnis erreichen können.
Nur der Code sieht viel schöner aus!
Ja jetzt höre ich euch schon, was erreichen wir damit der Code bleibt an der Zeile 16
doch stehen bis er fertig ist, jedoch so ist es nicht.
Das Programm läuft genau so wie im ersten Beispiel.
DownloadData() wird bis zur Zeile 16 Ausgeführt und das Schlüsselwort Async bewirkt, dass das Programm
in der Main Methode solange Fortgesetzt wird bis die Daten heruntergeladen wurden.
Sobald die Daten vorliegen, läuft das Programm dann ab Zeile 16 weiter.
Link: Visual Studio Async CTP
Ja so ist nun einmal, auch eine Basta geht leider einmal zu ende.
Ich hatte das Glück, dass ich die Basta Spring in der Zeit vom 22.Februar - 24.Februar in Darmstadt besuchen durfte. Eigentlich geht diese Konferenz ja über 5 Tage (22.Februar - 24.Februar) jedoch auch ohne die Workshops, kann man einige neue Erfahrungen und neue Sichtweisen mit nach Hause nehmen.
In der nächsten Zeit beabsichtige ich, einige dieser Informationen an euch weiterzugeben.
Also wenn Ihr gerade am überlegen seid, ob Ihr die nächste Basta besuchen wollt, mein Rat kann dann nur JA lauten.
Mehr Beiträge
Nächste Seite »