.NET Framework Programmierung

Inhalte:
Thematik
Das .Net Framework 4.0 und die Klassen-
Bibliothek bieten interessante Technologien,
um relativ einfach Anwendungen zu schreiben,
die auch komplexen Anforderungen gerecht werden.

Für wen ?
Entwickler die die Fähigkeiten des
.NET Frameworks und der Klassenbibliothek
ausnutzen wollen.

Das sollten Sie mitbringen !
Programmierkenntnisse in C# oder VB.NET

Was bringt es Ihnen ?
Ein solides Wissen über die Fähigkeiten
des .Net Frameworks, hilft Ihnen solche
Techniken vorteilhaft einzusetzen. 


Dauer   5 Tage

Der Kurs wird wunschgemäß in C# oder VB.NET gehalten
Seminare in C# oder in VB.NET

Einführung in .NET
Objektorientiert programmieren mit .NET
NET Framework Programmierung

Windows Forms Anwendungen
Vektor-orientierte Oberflächen mit WPF

Web Programmierung

Verteilte Anwendungen mit WCF

Andere Seminare
COM-Programmierung mit der ATL
OOP mit C++
Programmieren mit C
OOP mit Java

<<   Das Net Framework

Was stellt uns das Framework zur Verfügung ?
Technologien und die Tools für skalierbare Anwendungen mit Fokus Intranet / Internet,
aber nicht nur.

Unterstützt werden plattformneutrale Technologien und Protokolle wie
SOAP = HTTP +  XML. Das .Net-Framework - mehr als eine Klassenbibliothek.

Die Common-Language-Runtime,
ihre Aufgaben : Garbage Collection, eingebautes Typsystem, dadurch
sprachübergreifend, einfache Installation, Versionierung vorhanden und
vor allem Security.

<<   Managed Code

"Hello World" in C# , unsere erste Console Anwendung mit dem Notepad erstellt.
In .Net gibt es keinen Code außerhalb von Klassen.

Bei mehreren tausend Klassen bedarf es einer gewissen Ordnung - der Namespace.
Ein Namespace verschafft uns Zugriff auf Namen, nicht auf Code.
"Using Namespace" erspart Schreibarbeit.
Hat der Compiler Probleme damit, dann bitte voll qualifizieren. 

Wie wird der Code im Managed Execution Environment ausgeführt ? 
Code just in time oder komplett kompilieren mit Ngen ?
 
Wie wird das Programm kompiliert ?
Was bekommen wir ?  Ein Assembly, eine ausführbare Einheit.
Was enthält ein Assembly ? Code und viel Information dazu - die Metadaten.

Der "Missel" (MSIL) Code arbeitet wie eine Stackmaschine.
MSIL ist einfach, es gibt auch gar nicht so viele Befehle.
Den können wir uns anschauen, dafür gibt es den Disassembler ILDASM.

Wir reden auch noch über AppDomains - Miniprozesse, und warum es so etwas gibt.

<<   Arbeiten mit Komponenten

Wie erstellt man wieder verwendbare Komponenten in .Net ?
Die Erstellung in .Net ist trivial. Sie reduziert sich auf das Schreiben von Klassen.

Diese Klassen werden in eine ClassLibrary gepackt.
Dafür gibt es im Visual Studio ein Template.

Die Komponente kann dann entsprechend referenziert in Console, 
Windows Forms und Web Forms Anwendungen eingebunden werden.

Sie entspricht einem Inprocess Server in COM.

Wie werden Komponenten erstellt ?
Im NotePad und kompilieren auf der Kommando Zeile.

Im Visual Studio.  
Wir erstellen 3 gleiche Komponenénten in C# , VB.NET und C++ mit Extensions.  
Wir erstellen verschiedene Clients: Console-, Windows Forms- und Web Forms Client .

<<   Module und Assemblys

Module sind allein nicht lauffähig, sie können aber bei Bedarf zur Laufzeit
nachgeladen werden.

Assemblys sind ausführbar und enthalten ein Manifest, ein Inhaltsverzeichnis über
alle referenzierten Dateien und Typen.

Assemblys können aus einer oder auch aus mehreren Dateien bestehen.
Sie sind versionierbar, sofern sie einen “Strong Name” haben.

Welche Arten von Anwendungen gibt es in .NET ?

<<   Das Common Type System

CTS, ein gemeinsames Typsystem für alle Sprachen, die Basis für das 
Sprachübergreifende Programmieren.

Alle Typen in .Net  sind Objekte, auch einfache Typen wie short oder int. Diese
Objekte werden aber als Wert-Typen auf dem Stack und nicht auf dem Heap angelegt.

Auch Strukturen sind Werttypen. Wie werden sie deklariert und verwendet ?

Enums gehören ebenfalls dazu, sie können durch beliebige Typen implementiert werden, 
außer durch char. 

Namensgebung: Pascal und camelCasing, wo bleibt die wirklich sinnvolle 
ungarische Notation ?

In C# gibt es 2 Arten Zahlen zu formatieren: mit speziellen Format-Strings 
oder mit der Custom - Formatierung

Der Compiler erzeugt keinen Fehler bei Overflow, noch nicht einmal eine Warnung. 
Dafür gibt es aber ein "checked" - Keyword, das eine Exception erzeugt, 
diese kann man behandeln.

<<   Die Klasse String und StringBuilder

Enthält Unicode Zeichen ( 2 Byte ). String ist ein Alias für "System.String"

Strings sind nicht veränderbar, daher "Thread-Save", Methoden, die einen String 
zurückgeben, erzeugen einen neuen String.

Für den Referenz Typ String, sie werden auf dem Heap angelegt, ist die Equals-Methode
innerhalb der String Klasse auf  Wert-Vergleich überschrieben worden.

Die Klasse StringBuilder erzeugt bei Änderungen im String nicht jedes Mal ein
neues Objekt,  sie ist gerade in Schleifen der Klasse String vorzuziehen.

<<   System.Object

Alle Klassen in .Net sind von der Klasse "System.Object" abgeleitet.
Die Klasse "System.Object" liefert eine gewisse Grundfunktionalität, einige Methoden
sollten überschrieben werden.

ToString () liefert per Default den Namen der Klasse, sie sollte für einen
Werte-Vergleich überschrieben werden.

GetHashCode() liefert per Default eine fortlaufende Nummer und sollte eine
eindeutige Zahl  liefern.

Wenn Methoden wie Equals überschrieben werden, so müssen auch Operatoren
wie  "==" und "!=" überschrieben werden.
Wie schaut die Implementierung einer Klasse, aus wenn diese Methoden und die
Operatoren entsprechend überschrieben werden ?

<<   Arrays

In C# wird ein Array anders deklariert als in C oder C++.
Die Größe des Arrays ist nicht Bestandteil des Arrays.

Arrays werden immer mit "new" angelegt, auch wenn man es nicht so schreibt.  
Arrays sind Objekte in .Net, sie werden auf dem Heap angelegt.
Arrays haben Methoden.

Mehrdimensionale Arrays.

Array Member enthalten selbst ein Array: Das "Jagged Array".

Der Zugriff bei Arrays erfolgt über den Index.
Nützlich: das Length Property und die GetLength Methode.   

Wie übergebe ich Arrays in Funktionen, wie greife ich darauf zu ?
Der Zugriff auf die Command Line Argumente.

<<   Exceptions

Warum Exceptions ? Die Realisierung mit try catch.
Vorsicht! Exception Objekte sind nur im Catch Block gültig.

Verschiedene Exception Klassen in .Net.

Mehrfache Catch Blöcke : zuerst spezifische Exceptions dann allgemeine 
Exceptions abfangen. Abgeleitete Exception Klassen dürfen nicht hinter Basis 
Klassen stehen.

Bitte Exceptions auch nur für Ausnahmen verwenden, nicht für den  normalen
Programmablauf !

Mit "throw" Exceptions auslösen.

Wir können auch eigene Exception-Klassen erstellen.

Der Finally Block wird immer angesprungen, ein guter Platz zum Aufräumen.

Mit checked das Overflow Problem behandeln.


<<   Interfaces

Ein Interface hat eine "Feature Charakteristik", implementiert eine Klasse ein Interface
so kann es z.B. Sortieren, Enumerieren, ein Kopie von sich erstellen etc.

Ein "Hello World" Interface : Das Interface legt den Prototyp der Methoden fest,
die davon abgeleitete Klasse muss alle Methoden des Interfaces implementieren.

In .Net gibt es keine Mehrfachvererbung wie in C++, abgeleitete Klassen können
nur von einer Basis Klasse Code erben, sie können aber von beliebig vielen
Interfaces abgeleitet sein. Das funktioniert, da hier kein Code sondern nur Prototypen
von Funktionen vererbt werden, und die enthalten keinen Code.

Es sollte vor der Verwendung des Interfaces grundsätzlich geprüft werden, ob die
Klasse dieses auch implementiert hat, dafür gibt es Operatoren. 

Neben dem Polymorhismus über die Vererbung gibt es auch den Polymorhismus
über Interfaces. Dieser ist oft passender, da er unabhängig von einer
Vererbungshierarchie arbeitet: Auf diese Weise können eigene Klassen von der
Klassenbibliothek profitieren, wenn sie bestimmte Interfaces implementieren.
Implementiert z.B. die eigene Klasse die beiden Enumerations-Interfaces so kann man
eine "foreach" - Anweisung über die eigenen Klassen machen.

Die Implementierung des Interfaces kann sich auch in einer Basisklasse befinden.
Vorsicht bei Vererbung : Eine abgeleitete Klasse enthält eine Methode, die den 
gleichen Namen hat wie eine vererbte Interface Methode.
Das ist auch der Grund, warum man bei Interfaces stets über das Interface und
nicht über das Objekt auf die Interface Methoden zugreifen sollte. 

<<   Collections

Welche gibt es ?

Die ArrayList kann in der Anzahl der enthaltenen Elemente wachsen.
im Gegensatz zum Array : Dies hat eine feste Größe. Der Zugriff  ist einfach
und intuitiv.

Wie werden Queues und Stacks verwendet ?
Queue:  für ein "First-In", "First-Out" Verhalten. Die Methode Enqueue() fügt ein Objekt 
am Ende der Queue an. Dequeue() entfernt ein Element am Anfang der Queue.

Stack : für ein "Last-In", "First-Out" Verhalten mit Push und Pop.

Hash-Tabellen werden für schnelle Lookups verwendet.
Ein Key wird in einer Hash-Funktion in eine ganze Zahl umgewandelt
diese Zahl dient als Index für eine Hash-Tabelle.
Ein Englisch - Deutsch Übersetzungsprogramm mit einer Hash-Tabelle
Was sollte man bei Hash-Tabellen beachten ?

<<   Boxing

Das Arbeiten mit Wert-Typen (wie short, int, long etc.) ist am effizientesten.

Es besteht daher oft der Wunsch mit Wert Typen zu arbeiten und sie bei Bedarf
in Objekte umzuwandeln. Dies ermöglicht die Verwendung von Methoden, die
die Basisklasse System.Object als Parameter verwenden.

Vorsicht beim Boxing in Zählschleifen ! Hier kann optimiert werden.

<<   Delegates und Events

Wozu eignen sich Delegates ?  Wie werden sie verwendet ? 
Wie funktionieren Delegates ?

Das Keyword "delegate" erzeugt eine Klasse.

Hello World mit Delegates.

Anonyme Aufrufe mit Delegates, Klassen arbeiten zusammen ohne sich zu kennen.

Das Eventhandling basiert auf dem "Publisher-Subscriber" -  Pattern.
Das Eventhandling verwendet Delegates.

Wie werden mehrere Eventhandler registriert ?

Delegates ermöglichen Multicasting.

<<   Der Garbage Collector und das IDisposable Interface

In .Net entsorgt ein intelligenter Garbage - Collector den Speicher auf dem Heap.

Ist der Speicher knapp, sucht er nach Objekten, die nicht mehr referenziert werden.
Diese wandelt er wieder in Raw - Memory um und stellt zusammenhängenden
Speicher zur Verfügung.

Der Zeitpunkt der Entsorgung ist unbestimmt und erfolgt ggf. nie, sofern der
Speicher ausreicht. Was ist aber mit Resourcen wie z.B. File-Handles, die nach
Gebrauch sofort wieder freigegeben werden sollten, weil andere darauf warten ?

Man hat zwar keinen Einfluss darauf, wann ein Objekt zerstört wird, kann aber
dafür sorgen, dass vorher noch Code ausgeführt wird, bevor es entsorgt wird.

Erster Lösungsansatz: Objekte im .Net Framework haben einen virtuelle
Finalize Methode, die im eigenen Objekt überschrieben wird. In C# ist die
Methode über einen Destruktor aufrufbar.

Die bessere Lösung: Die Klasse implementiert zusätzlich das IDisposable Interface
mit seiner Dispose() Methode. In der Dispose Methode wird die Ressource freigegeben. 
Diese Methode sollte der Benutzer der Ressource aufrufen, vergißt er den Aufruf,
greift immerhin noch die überschriebene Finalize Methode.

<<   Data Streams & Files

Es gibt eine große Zahl von Klassen für die Ein-/Ausgabe in der Klassenbibliothek.

Die Basis ist die Stream - Klasse, eine abstrakte Klasse, die Daten byteweise auf 
Speicher Medien wie Disk und Speicher oder in Strings und Files schreibt.

Wohin letztlich geschrieben oder von wo gelesen wird, bestimmen von Stream 
abgeleitete instantiierbare Klassen wie FileStream und MemoryStream etc. 
So gibt auch eine Klasse NetworkStream, die Sockets wie Streams behandelt.
Mit Objekten der Klasse CryptoStream kann das Lesen und Schreiben verschlüsselt
werden. 
  
Geschrieben und gelesen wird über die Writer und Reader Objekte. Die BinaryReader
und BinaryWriter verarbeiten z.B. einfache Typen wie int oder long. StreamReader
verarbeiten Character fur Streams. StringReader und StringWriter verarbeiten
Character für Strings.

Der Klassenaufbau mutet zwar etwas überdimensioniert an, wir erreichen aber dadurch 
auch eine nie da gewesene Universalität.
  
Intern repräsentiert die CLR alle Charakter im Unicode Format. Unicode kann jedoch
uneffizient sein, wenn viele Zeichen über das Netzwerk transportiert oder in Files 
abgespeichert werden. Um die Effizienz zu erhöhen stellt das .NET Framework Klassen
zur Verfügung, die von der abstrakten Klasse System.Text.Encoding abgeleitet sind.
  
Diese Klassen kodieren und dekodieren Unicode in die üblichen Übertragungsformate
ASCII, UTF-7, UTF-8 und beliebige Übertragungsformate. 
Die Konstruktoren von BinaryReader, BinaryWriter, StreamReader oder StreamWriter 
ermöglichen die Wahl des Formats. Default Wert ist UTF-8.


<<   Internet Access

Das .Net Framework liefert eine Implementierung von Internetdiensten
die mehrschichtig und erweiterbar ist. Man kann sie einfach in eigene Anwendungen einbinden.

Die Namespaces System.Net and System.Net.Sockets Namespaces
enthalten Klassen zum Senden und Emfangen von Daten über das Internet.
Ihre Funktionalität ähnelt der von WinInet API.

Angewendet wird das Request / Response-Model. Wie ist der Vorgang ?
Der Client macht einen Request mit folgenden Angaben: Die Internet Ressource,
das Protokoll wie http, https. Falls erforderlich werden noch zusätzliche Daten wie
Proxy Server und Informationen zur Authentifizierung verwendet.
Die Antwort wird an die Client-Anwendung zurückgeschickt. Sie enthält die
eigentliche Information in Text- oder XML Form und zusätzliche Information wie Status,
Type of Content...

Das .NET Framework enthält Klassen zur Implementierung des Request / Response Modells.
Die WebRequest-Klasse enthält die Anfrage für eine Internet Resource, die
WebResponse-Klasse stellt einen Container für ankommende Antworten dar.
Zusätzlich wird eine Uri-Klasse verwendet, sie enthält den
Uniform Resource Identifier (URI ).
Die NetworkStream-Klasse wird verwendet zum Schreiben und Lesen der Daten.

Wir schreiben eine Console Anwendung zu Lesen einer Internet Seite.

Welche Klassen gibt es ?

Die NetworkStream-Klasse:
Ermöglicht  Web Daten in verschiedenen Formaten (HTML,XML..) zu senden und zu
empfangen. Es werden die Methoden Stream.Read() zum Lesen und Stream.Write()
zum Schreiben von Bytes verwendet. Sie enthält Methoden, die kompatibel zu
anderen Streams von .Net sind.
Nur wenige Zeilen Code reichen aus, damit eine Anwendung statt XML Daten aus
einem FileStream, Daten von einem Network Stream liest. Sie kann die Daten schon
beim Eintreffen verarbeiten.

Sockets:
Der System.Net.Sockets Namespace enthält eine Implementierung der
Windows Sockets Schnittstelle. Alle anderen Klassen für den Netzwerkzugriff setzen
auf dieser Socket Implementierung auf. Die Socket Klasse des .NET Frameworks 
ist eine in Managed Code geschriebene Version der Socket Dienste die vom
WinSock32 API zur Verfügung gestellt werden. In den meisten Fällen  marshaln
die Methoden die Daten für die Win32 Aufrufe und führen die notwendigen
Security Checks durch.

TCP and UDP Services:
Anwendung können TCP and UDP Services verwenden mit : TcpClient, TcpListener
und den UdpClient Klassen. Diese setzen auf den Socket Klassen auf, sie
repräsentieren die Daten als Network Streams. Sie kümmern sich auch um
Details beim Verbindungsaufbau.

Die TcpClient Klasse:
Die Methoden und Propertys abstrahieren die Details der Socket Erstellung 
Die Verbindung zum Internet wird durch einen Stream repräsentiert
Somit können Daten in einer allgemeinen Weise gelesen und geschrieben werden.

Die TcpListener Klasse:
Sie überwacht den TCP Port für eingehende Anfragen und erzeugt das Socket
Objekt, das die Verbindung zum Client verwaltet. Die Start-Methode enablet
das Horchen, die Stop-Methode disablet das Abhorchen des Ports, die
AcceptSocket-Methode nimmt eingehende Verbindungsrequests entgegen
und erstellt den Socket, der den Request behandelt. 

<<   Serialisierung

Möchte man Objekte auf Platte abspeichern bedient man sich in .NET der 
Serialisierung. Auch zum Transportieren in einen anderen Prozess, beim
Remoting, bedient man sich der Serialisierung.

Über die DeSerialisierung aus der abgespeicherten Bytefolge werden Instanzen 
mit dem gleichen Zustand wieder hergestellt.
 
Wenige Daten persistent zu speichern ist kein großer Aufwand, auch ohne
Serialisierung. Der Aufwand ist jedoch erheblich wenn eine Objekthierarchie
abspeichert werden soll, dann wenn zirkulare Referenzen auftreten.
  
Die CLR verwaltet das Layout von Objekten im Speicher anhand der Metadaten.
Dazu stellt sie einen automatischen Serialisierungs-Mechanismus zur Verfügung,
sie bedient sich der Reflection. Bei der Serialisierung werden folgende Daten 
abgespeichert: Name der Klasse, das Assembly und alle Daten Member.

Viele Klassen in der Klassenbibliothek lassen sich serialisieren.
Wie lässt sich z.B. der Inhalt einer ArrayList persistent abspeichern ?  

Wie kann ich eigene Klassen serialisierbar machen.
das wird mit Attributen gesteuert. Was ist dabei zu beachten ?

Wenn Daten berechnet werden, können Attribute nicht verwendet werden.
Dann greife ich zur Custom Serialisierung durch Implementieren des
ISerialize Interfaces. Wie funktioniert das ? 

<<   Remoting

Was ist Remoting ?
Remoting wird für verteilte Anwendungen eingesetzt und ist ein Ersatz für DCOM.
Ermöglicht die Kommunikation: zwischen Rechnern, Prozessen und AppDomains 

AppDomains sind Miniprozesse innerhalb eines Prozesses. Die CLR dient als
Remoting Infrastruktur. Sie enthält viele Klassen und verkapselt die Komplexität.
  
Was sind die Bestandteile beim Remoting ?  Channels, Messages und Formatter.

Channels transportieren Messages 
Die Message enthält den Funktionsaufruf oder Return Wert. 

Verschickt wird ein Stream über ein Transport Protokoll, folgende Protokolle werden
unterstützt: HTTP, TCP (Sockets), SMTP und eigene Protokolle.    

Formatter kodieren und decodieren Messages in einen Stream.
Soap Formatter: Die Message wird in XML kodiert und mit Soap Headern 
in einen Byte Stream serialisiert.

Binary Formatter: Message in einen binären Byte Stream serialisieren 
Es sind auch eigene Formatter möglich.
   
Wer sind die Teilnehmer beim Remoting ?
Üblicherweise besteht eine Remoting Anwendung aus 3 Teilen:
Dem Remote Objekt selbst, üblicherweise verpackt in eine DLL, eine Server
Anwendung, die das Remote Objekt hostet und ein Client der die Funktionalität
des Remote Objekts verwenden möchte.
  
Wie wird das ganze gestartet ?
Das Remote Objekt muss zunächst aktiviert werden, bevor es verwendet werden
kann, das findet im Host statt. Es gibt 2 Möglichkeiten, die Server- und
Client Aktivierung.
      
Die Server Aktivierung wird verwendet, wenn die Anzahl der Clients hoch ist, der
Funktionsaufruf erzeugt jedesmal ein neues Remote Objekt das nach dem Aufruf 
wieder entsorgt wird. Das entspricht der statuslosen Programmierung in COM+.
Vorteil: sehr gut skalierbar, Nachteil ein Increment über mehrere Aufrufe funktioniert
so natürlich nicht.
 
Ein Statusbehaftetes Verhalten ist bei der Server Aktivierung dennoch möglich 
sofern nur 1 Objekt erzeugt wird, z.B. für ein Singleton. Alle Clients arbeiten dann mit 
dem gleichen Objekt. 
     
Bei der Client Aktivierung setzt der Client zunächst eine Aktivierungsanforderung 
an das Remoting Framework ab. Vorteil: jeder Client kann sein Objekt so erstellen 
wie er möchte, er kann also Konstruktor Parameter übergeben, außerdem behält das
Objekt zwischen mehreren Funktionsaufrufen seinen Status. Nachteil, das kostet
Performance und ist nicht so gut skalierbar.
Das Verhalten entsprecht dem von DCOM, die Lebensdauer wird hier über einen 
Lease Mechanismus geregelt.

Zu allen Aktivierungsmodi erarbeiten wir Beispiele.

<<   XML-WebServices

WebServices sind programmierbare Komponenten im Intranet oder Internet.

Der Aufruf erfolgt in XML codiert, das Protokoll ist HTTP, das zusammen kennen wir
auch als SOAP. 

Das bringt bedeutende Vorteile: Da XML und HTTP auf allen gängigen
Betriebssystemen vorhanden ist, bietet sich der WebService als ideale
Betriebssystem-Unabhängige-Verbindungs-Komponente an. 

Funktionalität in welcher Sprache auch immer geschrieben oder vorhanden, kann
relativ einfach auf der einen Maschine in einen Web Service verpackt werden.
Der Web-Service mag hier nur als Wrapper dienen. 

Dieser Service kann von jeder Maschine verwendet werden, die XML über HTTP
ansteuern kann. Das Internet / Intranet werden somit zu Business Layer.

Das bringt aber auch Nachteile : Sicherheit ist mehr denn je gefragt.

Wir erstellen einen einfachen Web-Service, der rechnen kann. Wie geht das
im Visual Studio ?

Wie kann ich meinen WebService testen ? Das geht sehr komfortabel im VS Studio.

Was ist UDDI ? Was ist WSDL ?

Wie steuere ich einen WebService über einen Proxy an ?

<<   Einführung in Multithreading

Das .NET Framework liefert ein Design Pattern für die asynchrone Programmierung.
Es basiert auf den Delegate Klassen. Sie stellen neben den synchronen Methoden
auch asynchrone Methoden zur Verfügung.

Eigene Klassen können sich der Musterlösung bedienen und somit auf einfache Art
eine asynchrone Verarbeitung realisieren.

Asynchroner Support wird von vielen Klassen unterstützt wie IO, Sockets, Networking,
XML Web Services, Messaging etc.

Die asynchrone Verarbeitung beginnt mit dem Aufruf "BeginInvoke (...)"
Zurückgegeben wird ein "IAsyncResult" - Interface. Danach gibt es mehrere
Möglichkeiten auf die Beendigung des asynchronen Aufrufs zu reagieren.

Der  Aufruf von EndInvoke() suspendiert den aufrufenden Thread solange bis das
Ergebnis vorliegt. Danach wird mit EndOperation() das Ergebnis abgeholt.

Die eleganteste Art an das Ergebnis zu kommen, ist eine Reaktion in einem
Eventhandler. Dazu übergeben wir dem Worker Thread die Adresse eines Eventhandlers.
Der Client kann also nach Absetzen des asynchronen Aufrufs sofort weiterarbeiten.
Ist das Ergebnis vorhanden informiert uns der Worker Thread und wir können das
Ergebnis im Eventhandler abholen.

Die dritte Möglichkeit ist das Pollen, dazu stellt das IAsyncResult Interface ein Property
"IsCompleted" zur Verfügung.

Wir sprechen noch über Timer Events und wie nicht Thread-Safe Windows-Forms
Controls behandelt werden müssen.

Zum Schluss erstellen wir einen asynchronen WebService und steuern ihn an. 

<<   InterOp

Der Weg von der .Net Welt  in die bisherige Windows Welt und umgekehrt.
Was ist mit dem vorhandenen Code in DLL's, COM Componenten, COM+ ?
Alles neu schreiben ? Wohl nicht.  

.NET Framework unterstützt die Zusammenarbeit mit unmanaged Code sehr gut.
Win32 DLL's werden über "PInvoke" angesprochen, COM Objekte über
Wrapper Klassen.  

Wie arbeitet PInvoke ?
Beim Aufruf einer PInvoke Methode wird eine exportierte Methode aus 
einer DLL aufgerufen. Alle notwendigen Informationen für den Methodenaufruf 
müssen in den Metadaten angegeben werden. Dazu deklariert der Benutzer die 
Methode und dekoriert sie mit Attributen.
 
Die angegebene DLL wird mit LoadLibrary(..) in den Speicher geladen, der Aufruf wird
ermittelt mit GetProcAdress(), Parameter werden auf den Stack gepusht, 
ggf. erfolgt ein Marshaling. Die unmanaged Funktion erhält die Kontrolle über
das Programm, im Fehlerfall wird  eine Exception ausgelöst.  

Wie arbeiten .Net und COM zusammen ? Über Wrapper Objekte.
Frei nach dem Motto "Jeder bekommt das was er braucht".  

.Net Client steuert COM Komponente an:
Sobald ein .Net Client ein COM-Objekt anspricht,  erstellt die CLR einen 
Runtime Callable Wrapper (RCW). Das ist ein Assembly, das die beiden "Welten"
abstrahiert.

Es gibt mehrere Möglichkeiten den Wrapper zu erstellen. Am einfachsten
geht es im VS Studio. Informationen zur Generierung des Wrappers bezieht .NET z.B:
aus Typinformationen von COM z.B. in Form einer Type Library, der DLL etc.
     
Eine andere Möglichkeit an den Wrapper zu kommen: Der Hersteller der Komponente
liefert das Assembly, Vorteil : Hersteller kann mit seinem Key das Assembly signieren.  

C++ Client steuert .Net Componente als COM Objekt, d.h. der C++ Client beschreitet 
den üblichen Weg einen COM  Server anzusteuern mit
CoInitialize(),CoCreateInstance(..)  usw.
Der COM Client braucht zur Ansteuerung aber eine TypeLibrary und einen
COM Server, der in der Registry eingetragen sein muss.
Dafür gibt es Tools. Beides muss von Hand gemacht werden. 

Wird ein .Net Komponente dann von einem unmanaged Client (VC++,VB) angesteuert, 
erzeugt die CLR einen COM Callable Wrapper (CCW). Alle Aufrufe laufen dann über 
diesen Wrapper.

<<   ADO.NET

Wir haben hier ein neues Konzept und keine Weiterentwicklung von ADO
Es ermöglicht skalierbare Anwendungen für Intranet und Internet.

Es gibt 2 Betriebsarten, den verbundenen Betrieb, realisiert mit einem 
clientseitigen Vorwärts-Lese-Cursor, dem DataReader und dem nicht 
verbundenen Betrieb mit einer "InMemory" - Datenbank, dem DataSet.

Anhand von Anwendungs-Szenarien werden wir beide Betriebsarten behandeln.

Innerhalb des Visual Studio ist es ganz einfach auf den SQL-Server zuzugreifen.
Das erspart ein ständiges Wechseln vom Enterprise - Manager zum Visual Studio. 
Für unsere Arbeiten erstellen wir uns zunächst eigene Tabellen im Visual Studio.

Der DataReader empfiehlt sich für Datenanzeige in List- und ComboBoxen, 
die Daten sollen nur gelesen werden.

Welche Klassen sind im verbundenen Betrieb erforderlich ?

Welche Provider stehen uns für die unterschiedlichen Datenbanken zur Verfügung ?

Möchte man neben der Anzeige von Daten auch die Daten verändern und 
rückwärts scrollen, dann bietet sich der DataSet an. 

DataSets enthalten neben Tabellen auch Constraints und Relationen und 
ermöglichen auf diese Weise schon eine Vorabprüfung bei bestimmten 
Veränderungen der Daten innerhalb des DataSets. Sie ersparen dadurch einen 
fehlerhaften Zugriff auf die Datenbank.

DataSets arbeiten völlig losgelöst von ihrer Datenquelle, d.h. sie 
müssen nicht ihre Daten immer von Datenbanken beziehen. Andere Quellen sind
z.B. XML - Files und Web-Services.

Wie arbeiten wir mit einem DataSet ohne Datenbank ?
Welche Klassen haben wir zur Verfügung um ein eigenes Schema zu erstellen ?
Der XSD-Designer, ein nützliches Tool. Darin erstellen wir unser Schema.

Wir stellen Daten im DataSet mit Hilfe eines DataGrid dar, die Daten  werden
per Programm hinzugefügt.

Wie schreiben wir DataSets in XML-Files, welche Schreib-Modi stehen zur Verfügung ?

Nachdem wir gesehen haben, wie ein DataSet funktioniert, arbeiten wir mit dem
Data-Adapter-Wizard vom Visual Studio und erzeugen mit minimalen Code eine
funktionierende Anwendung.

Der Wizard erzeugt einen Typed DataSet und den erforderlichen Code für den
DataAdapter. Über den DataAdapter erfolgt der Query auf die Datenbank.
Mit einem Befehl können wir auch Änderungen im DataSet wieder in der Datenbank
speichern.

Die dazu nötigen Command - Objekte sind im DataAdapter Objekt enthalten. 
Der DataAdapter ist das Verbindungsglied zwischen Datenbank und DataSet. 
Hierüber erfolgt der Zugriff zum Lesen und zum Update.

<<   Attribute

C# ermöglicht auf eine einfache Art den Sprachumfang zu erweitern.

Über Attribute wird die Runtime aufgefordert beispielsweise Objekte in eine
Transaktion einzubinden.

Attribute sind deklarative Tags, die der Runtime Informationen übermitteln.
Sie werden mit den Metadaten der Elemente abgespeichert.

Das .NET Framework liefert eine Menge vordefinierter Attribute.
Die Runtime enthält Code, um die Werte der Attribute zu lesen und auf sie zu reagieren.

Wie werden die Attribute ausgewertet ?

Man kann auch eigene Attribute erstellen.  Wie werden sie erstellt und verwendet ?