2. Agenda
• Die Synchrone Welt?
• Warum Asynchronität?
• Asynchrone Programmierung mit .NET
• Asynchrone Web-Entwicklung
• Asynchrone System-Architektur
3. Die Synchrone Welt?
• In der Programmierung „der erste
Schritt“
• Stellen sie sich vor sie geben Ihre
Steuererklärung ab…
…und warten vor dem Zimmer bis sie ihren
Bescheid in der Hand halten?
• Synchronität in der „realen Welt“ …
…eine Utopie
4. Warum Asynchronität?
• Weil nicht schlimmer ist als Warten
• In der Zeit, in der sie auf den Steuerbescheid
warten…
… führen sie ihr Leben schliesslich auch weiter!
• Waruma also sollten ihre Applikationen
warten?
Auf eine Kalkulation, die Datenbank, den Host,
einen WebService …
7. Threads
• System.Threading.Thread
Start()
Sleep()
Suspend()
Resume()
Interupt()
• Wirft Exception
Abort()
• Wirft nicht abfangbare Exception
• Thread-Objekt kann nicht weiterverwendet werden
8. Threads
• Treads haben einen „Status“
Runnable
• Ready
• Standby
• Running
Not runnable
• Transition
• Waiting
• Terminated
9. Threads
• Systemkonzept: Pro Prozeß ein
ThreadPool
Anforderungen an den Pool über eine
Warteschlange
Muß eine Anforderung länger als eine halbe
Sekunde warten, wird neuer Pool-Thread
erzeugt
• Maximal 100 Threads
• Wird Pool-Thread 30 Sekunden nicht benötigt,
wird Thread aus dem Pool entfernt
10. Threads
• Ein Thread ist ein unabhängiger
Ausführungspfad innerhalb eines Prozesses
Jeder Thread besitzt seinen eigenen Kontext
• Stack, Programmzähler, Register etc.
• Threads verrichten Arbeit
Jeder Prozeß hat einen
• Kann aber beliebig viele haben
• Die Verteilung der Rechenzeit erfolgt auf
Threadbasis
11. Threads
• Kommunikation zwischen Threads
aufwendig
Synchronisation ist schwierig
Nur das Lesen und Schreiben von int ist
atomar
Alles andere muß synchronisiert werden
13. Threads
• Thread kann lokalen, eigenen Speicher
haben
Dynamisch: Thread Local Storage (TLS)
Statisch: Thread-spezifische Felder
• Referenztypen möglich, aber problematisch!
• Statischer Konstruktor läuft nur einmal
14. Threads
class Class1
{
[ThreadStatic]
static int s_Amount
public void Book()
{
LocalDataStoreSlot dataSlot =
Thread.GetNamedDataSlot("MyTlsSlot");
Thread.SetData(dataSlot, 10);
Console.WriteLine(
"Book amount for thread '{0}' = {1}",
Thread.CurrentThread.Name,
(int)Thread.GetData(dataSlot));
}
}
17. IAsyncResult design pattern
• Implementierung mit je zwei Methoden
BeginOperationName
• Startet die asynchrone Operation
• Rückgabewert ist eine implementation von
IAsyncResult
EndOperationName
• Beendet die asynchrone Operation
• Rückgabewert ist der selbe wie bei der
entsprechenden synchronen Operation
18. IAsyncResult design pattern
• IAsyncResult hält Informationen über die
asynchrone Operation
AsyncState
• Optionaler applikations-spezifische Informationen
AsyncWaitHandle
• Blockt den Zugriff auf Daten solange die Operation läuft
CompletedSynchronously
• Wurde die Operation auf dem aufrufenden Thread
beendet?
IsCompleted
• Ist die Operation beendet?
19. AsyncCallback
• Eigene CallBack-Methode
Aufruf nach Abschluss der asynchronen
Operation
Methodensignatur definiert durch einen
delegate
using System.Runtime.InteropServices;
namespace System
{
// Summary:
// References the callback method to be called when
// the asynchronous operation is completed.
[Serializable]
[ComVisible(true)]
public delegate void AsyncCallback(IAsyncResult ar);
}
20. Event-based Asynchronous Pattern
• Implementierung mit zwei Methoden …
OperationNameAsync
• Startet die asynchrone Operation
OperationNameAsyncCancel
• Bricht die laufende Operation ab
• ... und einem Event
OperationNameCompleted
• Feuert wenn die Operation abgeschlossen ist
21. Event-based Asynchronous Pattern
• Benutzen
Objekt instanziieren
Ereignissbehandlung and event anhängen
OperationNameAsync aufrufen
using System;
namespace System.ComponentModel
{
/// <summary>Represents the method that will handle the
/// MethodNameCompleted event of an asynchronous operation.
/// </summary>
public delegate void AsyncCompletedEventHandler(
object sender,
AsyncCompletedEventArgs e);
}
22. Asynchrone Web-Entwicklung
• Asynchrone Methoden in der Web
Applikation aufrufen
ASP.NET Async Pages
ASP.NET Async Tasks
• RemoteScripting vs. AJAX
ASP.NET Client Side Callbacks
ASP.NET Atlas Framework
23. ASP.NET Async Pages
• Page-Directive Attribute
• BeginEventHandler und/oder
EndEventHandler mit
AddOnPreRenderCompleteAsync
registrieren
BeginEventHandler bh = new BeginEventHandler(AsyncBeginPage);
EndEventHandler eh = new EndEventHandler(AsyncEndPage);
AddOnPreRenderCompleteAsync(bh, eh);
24. ASP.NET Async Tasks
• Page-Directive Attribute
• BeginEventHandler und/oder
EndEventHandler als Task mit
RegisterAsyncTask registrieren
PageAsyncTask myTask =
new PageAsyncTask(
AsyncBeginPage, AsyncEndPage,null, null);
RegisterAsyncTask(myTask);
25. ASP.NET Async …
• Infastruktur zum „Einklinken“ von ansynchron
auszuführendem Code
• „Seamless integration“ of coding model
Sieht aus wie Page_EventName
Steht an der gleichen Stelle wie
Page_EventName
Ist aber asynchron
• 7-10% Performancegewinn
Durch „bessere Nutzung“ der Threads in
ThreadPool
26. The Web from the client side
• Nach dem initialen Request/Response und
dem anzeigen der Seite wird bei jedem
„Klick“ ein Request/Response ausgeführt.
• Im „Hintergrund“Daten übertragen.
• Nur Daten übertragen die benötigt werden.
Keine Navigation, Grafiken oder Markup – Daten.
• Requirements: Scriptingfähigkeit des Browsers
27. RemoteScripting vs. AJAX
• RemoteScripting
Ein Java Applet/ActiveX Control leitet
clientseitige Anfragen an den Server
• Nachteil: Java/ActiveX benötigt
• Vorteil: Broadcast möglich
• AJAX
Javascript: Events und XmlHttpRequests
• Vorteil: NUR Scriptingfähigkeit des Browsers
• Nachteil:
– Keine „Events“ vom Server
– Ugly Code...
28. AJAX
var request = new Request();
function _getXmlHttp()
{
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
var progids=["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]
or (i in progids) {
try { return new ActiveXObject(progids[i]) }
catch (e) {}
}
@end @*/
try { return new XMLHttpRequest();}
catch (e2) {return null; }
}
function Request() {
this.Get = Request_get;
this._get = _getXmlHttp();
if (this._get == null) return;
}
...
29. AJAX
...
ReadyState = { Uninitialized: 0, Loading: 1, Loaded:2, Active:3, Completed: 4 }
HttpStatus = { OK: 200, NotFound: 404 }
function Request_get(url, f_change, method) {
if (!this._get)
return;
if (method == null)
method="GET";
if (this._get.readyState != ReadyState.Uninitialized)
this._get.abort()
this._get.open(method, url, true);
if (f_change != null)
var _get = this._get;
this._get.onreadystatechange = function()
{
f_change(_get);
}
this._get.send(null);
}
30. AJAX
...
function ajaxInnerHTML(method, args, elmId)
{
request.Get(
url + "?m=" + escape(method) + "&p=" + escape(args),
function(result)
{
if (result.readyState!=ReadyState.Complete)
return;
if (result.status==HttpStatus.OK
&& result.responseText != "")
{
elm = document.getElementById(elmId);
if(elm)
{
var response = result.responseText;
elm.innerHTML = response;
}
}
});
}
31. AJAX
• Funktioniert nur mit „Ugly Hacks“
Oder nur mit einem Browser-Typ
• Javascript ist nicht typisiert
• ...
• Codieren wie Ende der 90er?
Welcome to WEB 0.5?
33. ASP.NET ClientSideCallbacks
public partial class _Default : Page, ICallbackEventHandler
{
protected string returnValue;
protected void Page_Load(object sender, EventArgs e)
{
string cb = Page.ClientScript.GetCallbackEventReference(
this, "arg", “ReceiveServerData", "");
ListBox1.Attributes["onchange"] =
cb.Replace(
"arg", "this.options[this.selectedIndex].text");
}
public void RaiseCallbackEvent(string eventArgument){
returnValue = "10";
}
public string GetCallbackResult(){
return returnValue;
}
}
34. Atlas
• Eine Serverseitiges Framework für AJAX
Plattform und Browser-Kompatibel
Objektorientierte Serverseitige API
Declaratives model
• Steuerelemente
Toolunterstützung für Designer und
Entwickler
Kostenlos, Supported, Einfach zu benutzen
37. ASP.NET und MessageQueing
• Anfrage in RequestQueue schreiben
• Warten auf eine Antwort:
using (MessageQueue responseQueue = new MessageQueue(queuePath))
{
responseQueue.MessageReadPropertyFilter.CorrelationId = true;
Message objMessage =
responseQueue.ReceiveByCorrelationId(
correlationId,
new TimeSpan(0, 0, 0, timeOut),
MessageQueueTransactionType.None);
}