Remotefähige und nicht remotefähige Objekte
Sie sollten stets bedenken, dass ein Objekt, das in einer Anwendungsdomäne erstellt wurde und aus diesem Grund für diese Anwendungsdomäne spezifisch ist, zwar direkt aus dieser Domäne heraus aufgerufen werden kann, jedoch besondere Ereignisse eintreten müssen, damit das Objekt außerhalb seiner Domäne verfügbar ist. Nicht jeder Objekttyp kann über die Grenzen der Domäne hinweg effizient veröffentlicht und verwendet werden. Aus diesem Grund müssen Sie entscheiden, welchen Objekttyp Sie basierend auf den Anforderungen der Anwendung veröffentlichen möchten. Es gibt zwei einfache Kategorien von Objekten für verteilte Anwendungen: nicht remotefähige Objekte und remotefähige Objekte.
Nicht remotefähige Objekte
Manche Objekte können ihre Anwendungsdomäne nicht verlassen. Sie werden niemals einem Marshalling unterzogen, da sie keine Serialisierungsmethode deklarieren. Diese nicht remotefähigen Objekte werden in der Anwendungsdomäne verwendet, in der sie auch erstellt wurden. Der Zugriff auf diese Objekte erfolgt direkt von dieser Anwendungsdomäne aus. Bei den meisten Basisklassen in der Klassenbibliothek von .NET Framework handelt es sich um nicht remotefähige Objekte. Nicht remotefähige Objekte können nicht in andere Anwendungsdomänen kopiert oder dort dargestellt werden. Auf diese Objekte kann nur aus der ursprünglichen Anwendungsdomäne heraus zugegriffen werden.
Remotefähige Objekte
Der Zugriff auf remotefähige Objekte kann mit einem Proxy von außerhalb der Anwendungsdomäne oder des Kontexts erfolgen. Remotefähige Objekte können aber auch kopiert werden, und die Kopien können außerhalb ihrer Anwendungsdomäne bzw. ihres Kontexts übergeben werden. Das bedeutet, dass einige remotefähigen Objekte als Verweis und andere als Wert übergeben werden.
Remotefähige Objekte können gut in einer weit verteilten Umgebung verwendet werden. Es gibt zwei Hauptarten von remotefähigen Objekten:
MBV-Objekte (Marshal-by-Value), die kopiert und aus der Anwendungsdomäne heraus übergeben werden.
MBR-Objekte (Marshal-by-Reference), für die ein Proxy erstellt und vom Client für den Remotezugriff auf das Objekt verwendet wird.
MBV-Objekte
MBV-Objekte (Marshal-by-Value) deklarieren ihre Serialisierungsregeln (durch Implementieren von ISerializable zum Implementieren der eigenen Serialisierung oder durch die Ergänzung von SerializableAttribute, wodurch das System angewiesen wird, das Objekt automatisch zu serialisieren), aber sie erweitern MarshalByRefObject nicht. Das Remotingsystem erstellt eine vollständige Kopie dieser Objekte und übergibt die Kopie an die aufrufende Anwendungsdomäne. Sobald sich die Kopie in der Anwendungsdomäne des Aufrufers befindet, erfolgen Aufrufe der Kopie direkt an die Kopie. Wenn MBV-Objekte als Argumente übergeben werden, werden sie außerdem als Wert übergeben. Außer das SerializableAttribute-Attribut zu deklarieren oder ISerializable zu implementieren, müssen Sie keine weiteren Schritte ausführen, damit Instanzen der Klasse als Wert über Anwendungs- und Kontextgrenzen hinweg übergeben werden.
Hinweis
Ab Version 1.1 von .NET Framework führt die Remoteinfrastruktur die Deserialisierung bestimmter Typen auf dem Server nicht mehr automatisch durch. Wenn dies auch in Ihrem Szenario der Fall ist, müssen Sie die Deserialisierungsebene des Servers auf Full festlegen, bevor der Server das MBV-Objekt deserialisieren und verwenden kann. Weitere Informationen finden Sie unter Automatische Deserialisierung in .NET Remoting.
Verwenden Sie MBV-Objekte, wenn aus Leistungs- oder Verarbeitungsgründen das Verschieben des vollständigen Status des Objekts und aller ausführbaren Funktionen in die Zielanwendungsdomäne sinnvoll ist. In vielen Szenarios kann so die Anzahl zeitraubender, zahlreiche Ressourcen in Anspruch nehmender Roundtrips über Netzwerk-, Prozess- und Anwendungsdomänengrenzen hinweg reduziert werden. MBV-Objekte können auch direkt von innerhalb der ursprünglichen Anwendungsdomäne des Objekts verwendet werden. In diesem Fall wird keine Kopie erstellt, da kein Marshalling stattfindet, und der Zugriff erfolgt effizient.
Es ist jedoch auch nicht unbedingt ratsam, eine vollständige Kopie über ein ausgelastetes Netzwerk zu übergeben, wenn die veröffentlichten Objekte sehr groß sind. Zudem werden keine Änderungen des Status des kopierten Objekts wieder an das ursprüngliche Objekt in der ursprünglichen Anwendungsdomäne zurückgegeben. Auf einer abstrakten Ebene ähnelt dieses Szenario dem einer statischen HTML-Seite, die von einem Clientbrowser angefordert wird. Der Server kopiert die Datei, schreibt sie in einen Stream, versendet und vergisst sie. Jede nachfolgende Anforderung ist dann lediglich eine weitere Anforderung für eine andere Kopie.
Sie erstellen einen Marshal-by-Value-Typ, indem Sie SerializableAttribute verwenden, sofern Sie keine Klasse erweitern, die ISerializable bereits implementiert. In diesem Fall müssen Sie ISerializable für Ihren Typ implementieren.
Das Remotingsystem verwendet sehr häufig serialisierbare Objekte. Ein Verweis auf ein Objekt in einer anderen Anwendungsdomäne, im Remotingsystem anhand der ObjRef-Klasse dargestellt, ist selbst serialisierbar. Es muss möglich sein, eine exakte Kopie zu erstellen und diese an eine Anforderung zu senden. Nachrichtenobjekte, die IMessage implementieren, da sie generische Container von Aufrufdaten und sonstigen erforderlichen Objektverweisen sind. Außerdem handelt es sich bei Objekten, die problemlos Daten übertragen, häufig um serialisierbare Objekte. DataSet z. B. erweitert die MarshalByValueComponent-Klasse, die ISerializable implementiert.
Benutzerdefinierte Ausnahmen bei Remoting
Systemdefinierte Ausnahmen sind immer Marshal-by-Value-Typen (sie implementieren die ISerializable-Schnittstelle), die beim Auslösen durch ein Remoteobjekt automatisch zum Aufrufer kopiert werden, wenn die Remotingkonfiguration dies zulässt. (Ab Version 1.1 von .NET Framework muss das <customErrors>-Element auf off festgelegt werden, damit Ausnahmen an den Aufrufer geleitet werden können.)
Weitere Informationen zum Erstellen eines Ausnahmetyps, der von einem Remoteobjekt ausgelöst und von einem Remoteaufrufer abgefangen werden kann, finden Sie unter Gewusst wie: Erstellen eines Ausnahmetyps, der von Remoteobjekten ausgelöst werden kann
MBR-Objekte
MBR-Objekte (Marshal-by-Reference) sind remotefähige Objekte, die mindestens System.MarshalByRefObject erweitern. Wenn ein Client eine Instanz eines MBR-Objekts in der eigenen Anwendungsdomäne erstellt, erstellt die .NET Remoting-Infrastruktur abhängig vom Typ der deklarierten Aktivierung in der Anwendungsdomäne des Aufrufers ein Proxyobjekt, das das MBR-Objekt darstellt, und gibt einen Verweis auf diesen Proxy an den Aufrufer zurück. Der Client ruft anschließend den Proxy auf. Remoting marshallt diese Aufrufe, sendet sie zurück an die ursprüngliche Anwendungsdomäne und startet den Aufruf des eigentlichen Objekts.
Hinweis
Wenn sich der Client in derselben Anwendungsdomäne befindet wie das MBR-Objekt, gibt die Infrastruktur an den Client einen direkten Verweis auf das MBR-Objekt zurück und verhindert so, dass unnötiges Marshalling ausgeführt wird.
Wenn ein MarshalByRefObject-Objekt als Parameter übergeben wird, wird es zu einem Proxy in der anderen Anwendungsdomäne, wenn der Aufruf eintrifft. MBR-Rückgabewerte und out-Parameter funktionieren auf dieselbe Weise.
Hinweis
Ab Version 1.1 von .NET Framework führt die Remoteinfrastruktur die Deserialisierung bestimmter Typen auf dem Server nicht mehr automatisch durch. Um z. B. Unterstützung für MBR-Objekte zu erhalten, die als Parameter übergeben werden, muss die Deserialisierungsebene des Servers auf Full festgelegt werden, bevor der Server den MBR-Parameter deserialisieren und verwenden kann. Weitere Informationen finden Sie unter Automatische Deserialisierung in .NET Remoting.
Verwenden Sie MBR-Objekte, wenn der Status des Objekts und alle ausführbaren Funktionen in der Anwendungsdomäne bleiben sollen, in der sie erstellt wurden. So sollte z. B. ein Objekt, das ein internes Feld aufweist, bei dem es sich um ein Handle des Betriebssystems handelt, MarshalByRefObject erweitern, da das Handle des Betriebssystems in einer anderen Anwendungsdomäne, in einem anderen Prozess oder auf einem anderen Computer keine Bedeutung hätte. Manchmal kann ein Objekt einen unzulässig großen Umfang haben. Bei einem robusten Server spielt dies keine Rolle, aber die Übertragung an ein Modem mit 33,6 KB/s könnte Probleme bereiten.
Kontextgebundene Objekte
Kontextgebundene Objekte sind MBR-Objekte, die von System.ContextBoundObject erben. System.ContextBoundObject wiederum erbt von System.MarshalByRefObject. Sie können sich einen Kontext als Untereinheit einer Anwendungsdomäne vorstellen, die eine umfangreiche Umgebung für die Objekte bereitstellt, die sich während der Ausführung darin befinden. Beispielsweise kann ein Kontext garantieren, dass auf die Objekte nicht von mehreren Threads gleichzeitig zugegriffen wird. Jede Anwendungsdomäne weist einen Standardkontext auf. Verwalteter Code erstellt meist Objekte und ruft Member direkt innerhalb derselben Anwendungsdomäne auf. Dabei wird der Standardkontext der Domäne verwendet, sodass keine kontextbezogenen Aspekte zu berücksichtigen sind. Alle Typen, die von ContextBoundObject erben, werden anderen Kontexten als Proxys verfügbar gemacht (unabhängig davon, ob sie sich in derselben oder in anderen Domänen befinden).
Stellen Sie sich z. B. vor, Sie hätten eine Methode für einen Typ, der Teil einer Transaktion und somit an Regeln gebunden ist, die spezifisch für den Kontext sind, in dem die Erstellung stattfand. Dieser Typ muss von ContextBoundObject erben, sodass auf das Objekt von seinem eigenen Kontext aus zugegriffen wird und das System die Regeln in Bezug auf die Transaktionen erzwingen kann, die dem Objekt und seinen Methoden zugeordnet sind. Wenn ContextBoundObject von einem anderen Kontext innerhalb derselben Anwendungsdomäne aufgerufen wird, wird für den Aufrufer ein Proxy erstellt, aber die kontextübergreifende Kommunikation findet nicht über das Channelsystem statt und steigert somit in dieser Situation die Aufrufeffizienz.
Da durch das Überschreiten von Grenzen Verarbeitungszeit genutzt wird, sollten Sie die vom Objekt zu überschreitenden Grenzen bestimmen, bevor Sie eine Entscheidung darüber treffen, welchen Typ eines remotefähigen Objekts der Server darstellen soll. Auf Objekte, die für einen bestimmten Kontext spezifisch sind, kann nur direkt von diesem Kontext aus zugegriffen werden. Dasselbe gilt für Objekte, die für eine bestimmte Anwendungsdomäne spezifisch sind. Um diese Objekte zu verschieben, muss das Remotingsystem erfolgreich eine Kontextgrenze, eine Anwendungsgrenze oder sogar beide überwinden, bevor das Serverobjekt von innerhalb der für das Objekt spezifischen Grenze aufgerufen werden kann. Wenn für das Aufrufen des Objekts keine Überprüfung des Kontexts erforderlich ist, sollten Sie verhindern, dass der Remotetyp ContextBoundObject erweitert, da in diesem Fall MarshalByRefObject vorzuziehen ist. Falls eine Überprüfung erforderlich sein sollte, sollten Sie ContextBoundObject erweitern. Bedenken Sie jedoch, dass die zusätzliche Grenze erst überwunden werden muss, bevor der Aufruf für das Objekt erfolgen kann.
Gültigkeitsbereich der Veröffentlichung
Unterschiedliche Remotingsysteme haben auch unterschiedliche Ansätze bei der Entscheidung darüber, welche Member und welcher Typ von Membern remote verwendet werden kann. .NET Remoting macht für andere Anwendungsdomänen Objekte so verfügbar, als ob diese sich auf dem lokalen Computer befinden würden, allerdings mit den folgenden Ausnahmen:
Statische Member.
Statische Felder und Methoden werden niemals remote verwendet, und der Feldzugriff erfolgt direkt über den Arbeitsspeicher. Bei .NET Remoting werden also stets Instanzmember irgendeiner Form verarbeitet.
Instanzfelder und Accessoren.
Bei Instanzfeldern und Accessormethoden fügt das System zur Laufzeit eine Überprüfung ein, um zu bestimmen, ob es sich bei dem Objekt um einen Proxy handelt. Wenn es kein Proxy ist, erfolgt der Feldzugriff direkt. Andernfalls stellt der Proxy Accessoren für den Aufrufer bereit.
Private Methoden.
Private Methoden können nicht remote verwendet werden. Es ist nicht möglich, einen Delegaten zu umfassen und remote an eine private Methode zu übergeben.
Delegaten.
Delegaten sind Marshal-by-Value-Objekte. Das Objekt innerhalb des Delegaten kann ein beliebiger Typ eines remotefähigen Objekts sein: ein serialisierbares Objekt, ein MarshalByRefObject-Objekt oder ein ContextBoundObject-Objekt. Die einzige Ausnahme besteht darin, dass kein erfolgreiches Remoting eines Delegaten für eine Schnittstellenmethode ausgeführt werden kann. Der Delegat umfasst die Implementierung der Schnittstellenmethode, wobei erforderlich ist, dass die Typinformationen des Clients für den Server verfügbar sind.
Außerkraftsetzen von Methoden für "Object".
Aus Leistungsgründen werden die virtuellen Methoden für Object-Methoden stets lokal in der Anwendungsdomäne ausgeführt, in der sie aufgerufen werden. Aufrufe einer der folgenden Methoden gehen nur an das Remoteobjekt, wenn diese Methoden für das Remoteobjekt außer Kraft gesetzt wurden:
Equals
Diese virtuelle Methode wird, falls sie außer Kraft gesetzt wurde, remote ausgeführt.
GetHashCode
Diese Methode wird lokal ausgeführt.
ToString
Diese virtuelle Methode wird, falls sie außer Kraft gesetzt wurde, remote ausgeführt.
Equals (die statische Version)
Diese Methode wird lokal ausgeführt.
MemberwiseClone
Diese Methode wird lokal ausgeführt.
Siehe auch
Aufgaben
Gewusst wie: Erstellen eines Ausnahmetyps, der von Remoteobjekten ausgelöst werden kann
Weitere Ressourcen
Übersicht über .NET Framework Remoting
Erstellen remotefähiger Objekte