Copyright © 2006 newtelligence® AG | All rights reserved
Asynchronous ASP.NET
Daniel Fisher(lennybacon)
Software Engineer
newtelligence® AG
Agenda
• Die Synchrone Welt?
• Warum Asynchronität?
• Asynchrone Programmierung mit .NET
• Asynchrone Web-Entwicklung
• Asynchrone System-Architektur
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
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 …
Asynchrone Programmierung mit
.NET
• Prerequisites
 Threads
 Timer
 Delegates
• IAsyncResult design pattern
• AsyncCallbacks
• Event-based Asynchronous Pattern
Threads
• Synchroner Ablauf
• Asynchroner Ablauf*
*Parallele Abfolgen NUR auf Multiprozessor-Maschinen
Threads
• System.Threading.Thread
 Start()
 Sleep()
 Suspend()
 Resume()
 Interupt()
• Wirft Exception
 Abort()
• Wirft nicht abfangbare Exception
• Thread-Objekt kann nicht weiterverwendet werden
Threads
• Treads haben einen „Status“
 Runnable
• Ready
• Standby
• Running
 Not runnable
• Transition
• Waiting
• Terminated
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
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
Threads
• Kommunikation zwischen Threads
aufwendig
 Synchronisation ist schwierig
 Nur das Lesen und Schreiben von int ist
atomar
 Alles andere muß synchronisiert werden
Threads
• Synchronisation
 lock{}-Statement
 System.Threading.WaitHandle
• System.Threading.Mutex
• System.Threading.AutoResetEvent
• System.Threading.ManualResetEvent
 System.Threading.Monitor
 System.Runtime.CompilerServices.
MethodImplAttribute
 System.Runtime.Remoting.Contexts.
SynchronisationAttribute
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
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));
}
}
Timer
• System.Threading.Timer
 Periodische Ausführung von Funktionalität
 Status wird in übergebener Objekt-Instanz
gehalten
 Deinitialisierung mit Dispose()
Delegates
• Funktionszeiger
• Basis für Events
• Asynchrone Aufrufe möglich
 IAsyncResult design pattern ...
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
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?
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);
}
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
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);
}
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
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);
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);
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
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
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...
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;
}
...
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);
}
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;
}
}
});
}
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?
ASP.NET ClientSideCallbacks
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head" runat="server“>
<script type="text/ecmascript">
function ReceiveServerData(rValue){
document.getElementById('Results').innerHTML = rValue;
}
</script>
</head>
<body>
<form id="form1" runat="server“>
<asp:ListBox ID="ListBox1" Runat="server“>
<asp:ListItem Text="Cheese" Value="Cheese" />
</asp:ListBox><br />
Items in stock:
<div id="Results" runat="server“ />
</form>
</body>
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;
}
}
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
Atlas
• ASPX
• CodeBehind
<atlas:ScriptManager ID="sm1" runat="server" EnablePartialRendering="true" />
<atlas:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:Button ID=“B" Text="GetData" runat="server" OnClick=“B_Click" />
<br />
<asp:Label ID="Message" runat="server" />
</ContentTemplate>
</atlas:UpdatePanel>
public partial class _Default : System.Web.UI.Page
{
protected void B_Click(object sender, EventArgs e)
{
Message.Text = "Button1 was clicked";
}
}
Asynchrone System-Architekturen
• Web-Server – Applikations-Server-Topologie
 Synchron
 Asynchron
• Entkoppelung durch MessageQueing
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);
}
Fazit
Copyright © 2006 newtelligence® AG | All rights reserved
Copyright © 2006 newtelligence® AG | All rights reserved

2006 - NRW Conf: Asynchronous asp.net

  • 1.
    Copyright © 2006newtelligence® AG | All rights reserved Asynchronous ASP.NET Daniel Fisher(lennybacon) Software Engineer newtelligence® AG
  • 2.
    Agenda • Die SynchroneWelt? • 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? • Weilnicht 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 …
  • 5.
    Asynchrone Programmierung mit .NET •Prerequisites  Threads  Timer  Delegates • IAsyncResult design pattern • AsyncCallbacks • Event-based Asynchronous Pattern
  • 6.
    Threads • Synchroner Ablauf •Asynchroner Ablauf* *Parallele Abfolgen NUR auf Multiprozessor-Maschinen
  • 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 habeneinen „Status“  Runnable • Ready • Standby • Running  Not runnable • Transition • Waiting • Terminated
  • 9.
    Threads • Systemkonzept: ProProzeß 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 Threadist 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 zwischenThreads aufwendig  Synchronisation ist schwierig  Nur das Lesen und Schreiben von int ist atomar  Alles andere muß synchronisiert werden
  • 12.
    Threads • Synchronisation  lock{}-Statement System.Threading.WaitHandle • System.Threading.Mutex • System.Threading.AutoResetEvent • System.Threading.ManualResetEvent  System.Threading.Monitor  System.Runtime.CompilerServices. MethodImplAttribute  System.Runtime.Remoting.Contexts. SynchronisationAttribute
  • 13.
    Threads • Thread kannlokalen, 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 ints_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)); } }
  • 15.
    Timer • System.Threading.Timer  PeriodischeAusführung von Funktionalität  Status wird in übergebener Objekt-Instanz gehalten  Deinitialisierung mit Dispose()
  • 16.
    Delegates • Funktionszeiger • Basisfür Events • Asynchrone Aufrufe möglich  IAsyncResult design pattern ...
  • 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 • AsynchroneMethoden 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 fromthe 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 nurmit „Ugly Hacks“  Oder nur mit einem Browser-Typ • Javascript ist nicht typisiert • ... • Codieren wie Ende der 90er? Welcome to WEB 0.5?
  • 32.
    ASP.NET ClientSideCallbacks <html xmlns="http://www.w3.org/1999/xhtml"> <headid="Head" runat="server“> <script type="text/ecmascript"> function ReceiveServerData(rValue){ document.getElementById('Results').innerHTML = rValue; } </script> </head> <body> <form id="form1" runat="server“> <asp:ListBox ID="ListBox1" Runat="server“> <asp:ListItem Text="Cheese" Value="Cheese" /> </asp:ListBox><br /> Items in stock: <div id="Results" runat="server“ /> </form> </body>
  • 33.
    ASP.NET ClientSideCallbacks public partialclass _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 ServerseitigesFramework 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
  • 35.
    Atlas • ASPX • CodeBehind <atlas:ScriptManagerID="sm1" runat="server" EnablePartialRendering="true" /> <atlas:UpdatePanel ID="up1" runat="server"> <ContentTemplate> <asp:Button ID=“B" Text="GetData" runat="server" OnClick=“B_Click" /> <br /> <asp:Label ID="Message" runat="server" /> </ContentTemplate> </atlas:UpdatePanel> public partial class _Default : System.Web.UI.Page { protected void B_Click(object sender, EventArgs e) { Message.Text = "Button1 was clicked"; } }
  • 36.
    Asynchrone System-Architekturen • Web-Server– Applikations-Server-Topologie  Synchron  Asynchron • Entkoppelung durch MessageQueing
  • 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); }
  • 38.
    Fazit Copyright © 2006newtelligence® AG | All rights reserved
  • 39.
    Copyright © 2006newtelligence® AG | All rights reserved

Hinweis der Redaktion

  • #13 WaitHandle can also be used for unmanaged resources.