Abteilung Verteilte Systeme Projektgruppe AspectIX Universität Ulm Fakultät für Informatik AVID-Übung 5 Asynchronous.NET Remoting 15. Juli 2004 Andreas I. Schmied (schmied@inf...)
Asynchrone Methodenaufrufe Informell: Aufruf wird initiiert Programm läuft lokal weiter Ergebnis wird später abgeholt Beispiel: Broadcast-Service Client schickt Nachricht an Service Service reflektivert Nachricht an alle Clients Service wird als Sender Remoting-Client Clients werden als Empfänger selbst Remoting-Server Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 2/13
Delegates und Events (1) Delegates typisierte Methodenzeiger, statisch oder objektgebunden Typ-Definition und Delegate-Variable 1 class MyService {... 2 public delegate void RadioHandler(String msg); 3 public RadioHandler radio; 4 } Client meldet sich signaturkonform an Delegate-Variable an 5 class MyClient {... 6 void register() { 7 MyService srv =...; 8 srv.radio += new MyService.RadioHandler(this.OnRadio); 9 } 10 void OnRadio(String msg) { 11 Console.WriteLine("Heard: "+msg); } } Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 3/13
Delegates und Event (2) Service erzeugt Nachricht an alle angemeldeten Delegates radio("you're listening radio AvID!"); Features (näheres s.u.) void-delegate-nachrichten automatisch asynchron, wenn Aufruf: <delegate-variable>(<formal parameters>, null, null); ", null, null" ~ ", AsyncCallback-Handler, <delegate-variable>" Methoden Begin/EndInvoke,... automatisch signaturkonform generiert Threadpooling und Synchronisation wird von.net bereitgestellt Probleme AVID-Übung 5 srv.radio =... überschreibt vorherigen (deshalb +=) Abmelden: srv.radio -=... Mehrere Delegates: non-void-rückgabewert nicht eindeutig (s.u.) Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 4/13
Delegates und Events (3) Nachteile von puren Delegates Delegate-Variablen sind public! Delegate-Variablen sind überschreibbar (=singledelegate, =null)! Delegate-Nachrichten sind öffentlich auslösbar! Lösung: Events MyService verwendet spezielle Event-Objekte (Zeile oben ersetzt) 3 public event RadioHandler radio; Compiler erzeugt nur public-methoden für Operatoren += und -= Event kann nur von Erzeuger ausgelöst werden statisch durch Compiler geprüft Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 5/13
Asynchrone Methodenaufrufe mit Rückgabe Behandlung über.net-callback-handler AsyncCallback Ergebnis wird über IAsyncResult bereitgestellt Beispiel: PI-Factory Annahme: mehrere Clients an pifevent angemeldet public delegate float PIF(int length); public event PIF pifevent;... for(pif pif in pifevent.getinvocationlist() ) pif.begininvoke(42, new AsyncCallback(this.Done), pif);... //...,null, null); private void Done(IAsyncResult res) { PIF pif = (PIF) res.asyncstate; float pi = pif.endinvoke(res); } AVID-Übung 5 Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 6/13
Asynchrones Remoting (1) Service: 1 class PiService {... 2 float computepi(int length) {... } 3 } Client: (ohne Callback:..., null, null) 4 delegate float PiDgt(int length); 5 PiService srv = new PiService(); 6 PiDgt del = new PiDgt(srv.computePI); 7 IAsyncResult ar = del.begininvoke(42, null, null); 8... 9 float pi = del.endinvoke(ar); Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 7/13
Asynchrones Remoting (2) Probleme: Begin/EndInvoke simuliert Nebenläufigkeit intern synchron mit eigener Connection pro Call Typauflösung in Soapsuds-generierten Assemblies schlägt fehl What the... %~# Work-around für SAOs soapsuds... -gc Attribut [... SoapType(...)] vor SAO-Klasse entfernen CAOs: what the hell... #Ox... #-P Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 8/13
Asynchrones Remoting mit lokalem Wrapper Client: (Listing erweitert, s.o.) 4 delegate float WrappedPiDgt(PiService s, int length); static float MyWrapper (PiService s, int length) { return s.computepi(length); } 5 PiService srv = new PiService(); 6 WrappedPiDgt del = new WrappedPiDgt(MyWrapper); 7 IAsyncResult ar = del.begininvoke(srv, 42, null, null); 8... 9 float pi = del.endinvoke(ar); Problem: zumindest noch synchron innerhalb Wrapper AVID-Übung 5 Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 9/13
Asynchone Events (1) Shared Assembly: namespace Shared { public delegate void RadioHandler(String msg); } public interface Radio { void send(string msg); event RadioHandler radio; } Server: class MyService : MarshalByRefObject, Shared.Radio { public override object InitializeLifetimeService() { return null; } // forever public event Shared.RadioHandler radio; } void send(string msg) { radio(msg); } Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 10/13
Asynchrone Events (2) Client: 1 class MyClient {... 2 void register() { 3 MyService srv =...; 4 MyHandler hdl = new MyHandler(); 5 srv.radio += new RadioHandler(hdl.OnRadio); } } 6 class MyHandler : MarshalByRefObject { 7 [OneWay] void OnRadio(String msg) 8 { Console.WriteLine("Heard: "+msg); } 9 public override object InitializeLifetimeService() 10 { return null; } // forever } [OneWay] asynchrone Methode ohne Rückgabe Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 11/13
Asynchrone Events (3) Probleme: Exception auf Serverseite erzeugt, weil: 1. Verbinden des Delegates mit der Event-Quelle 2. Deserialisierung auf Serverseite 3. Client-Assembly dort nicht verfügbar %~# Lösung: Adapter-Delegate-Klasse mit Deklaration in Shared-Assembly an Service angemeldet leitet Event an lokalen Client weiter Verhalten von [OneWay] im Server (++) Exception unterdrückt, falls Client-Fehler (--) Service probiert es jedesmal wieder (Aufwand!) manuelles Versenden in for (...GetInvocationList()) bei Exception einzeln Delegates entfernen (-=) Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 12/13
Copyright 2004 Andreas I. Schmied (schmied@inf...), Abteilung Verteilte Systeme, Universität Ulm 13/13