BlackCoin's Corner

In diesem Blog dreht es sich zu 90 % um den Themenbereich C# .Net
Unboxing Nokia Lumia 800

Heute war es endlich so weit.
Seit gerade eben bin ich Besitzer dieses schicken Pakets.

 

(Ja die Bilder sind nicht gerader der Hammer)

CIMG4936

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)

 

CIMG4938

IT schneller am Ziel, mit der NRW Conf 2011
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.

Posted: Aug 08 2011, 10:19 von Lars Schmitt | mit no comments
Abgelegt unter:
Happy Birthday .NETSNIPPETS.de
Happy Birthday

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.

Windows Azure Gewinnspiel

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.

Wie übergebe ich ein Array von POCO’s an den Controller in ASP .NET MVC 2

 

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.

tableSample

 

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.

Fehler

 

Um diesem Fehler auf die Spur zu kommen, könnte man sich z.B. die übergebenen Daten anschauen.uebergebeneDaten

 

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

fertig

Visual Studio 2010 Service Pack 1

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.

Posted: Mrz 08 2011, 07:04 von Lars Schmitt | mit no comments
Abgelegt unter:
verschiedene Pattern zur Objekt Instanziierung

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.

Optional and Named Parameters

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.

IL-Code-1

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

IL-Code-2

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!

Visual Studio Async CTP
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!Reagiertnicht

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
Posted: Feb 26 2011, 04:02 von Lars Schmitt | mit no comments
Abgelegt unter: ,
zurück von der Basta

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.

Posted: Feb 26 2011, 09:56 von Lars Schmitt | mit no comments
Abgelegt unter:
Mehr Beiträge Nächste Seite »