次の方法で共有


リモート処理可能オブジェクトとリモート処理不可能オブジェクト

このトピックの対象は、既存のアプリケーションとの下位互換性のために残されているレガシ テクノロジに特定されています。新規の開発には、このトピックを適用しないでください。分散アプリケーションは、現在は Windows Communication Foundation (WCF) を使用して開発する必要があります。

あるアプリケーション ドメイン内で作成されたアプリケーション ドメイン固有のオブジェクトは、そのドメインからは直接呼び出せますが、ドメインの外部から利用する場合は、事前になんらかの処理が必要です。オブジェクトの型には、ドメイン境界を越えると効率的に公開または利用できないものもあります。したがって、公開するオブジェクトの型は、アプリケーションの要件に応じて判断する必要があります。分散アプリケーションの場合、オブジェクトはリモート処理不可能オブジェクトとリモート処理可能オブジェクトという 2 つのカテゴリに分類できます。

リモート処理不可能オブジェクト

一部のオブジェクトは、アプリケーション ドメインの外に出ることはありません。これは、シリアル化のメソッドを宣言しないため、マーシャリングされないという理由によります。このようなリモート処理不可能オブジェクトは、それらが作成されたアプリケーション ドメイン内で使用するようにデザインされており、常にそのアプリケーション ドメインから直接アクセスされます。.NET Framework クラス ライブラリのほとんどの基本クラスは、リモート処理不可能オブジェクトです。リモート処理不可能オブジェクトを別のアプリケーション ドメインにコピーまたは表示することはできません。これらのオブジェクトには、元のアプリケーション ドメインからのみアクセスできます。

リモート処理可能オブジェクト

リモート処理可能オブジェクトは、そのアプリケーション ドメインやコンテキストの外部から、プロキシを使用してアクセスまたはコピーできます。また、コピーはアプリケーション ドメインやコンテキストの外部に渡すことができます。つまり、リモート処理可能オブジェクトには、参照によって渡されるものと、値によって渡されるものがあります。

リモート処理可能オブジェクトは、広範囲な分散環境でも適切に機能するオブジェクトです。リモート処理可能オブジェクトには、主として次の 2 種類があります。

  • 値渡しのマーシャリング オブジェクト。この種類のオブジェクトは、アプリケーション ドメインからコピーされて渡されます。

  • 参照渡しのマーシャリング オブジェクト。この種類のオブジェクトに対してはプロキシが作成され、クライアントによってオブジェクトへのリモート アクセスに使用されます。

値渡しのマーシャリング オブジェクト

値渡しのマーシャリング (MBV: Marshal-By-Value) オブジェクトは、独自のシリアル化を実装する ISerializable の実装、またはシステムにオブジェクトの自動シリアル化を指示する SerializableAttribute の指定によってシリアル化規則を宣言しますが、MarshalByRefObject を拡張することはありません。リモート処理システムは、これらのオブジェクトの完全なコピーを作成し、そのコピーを呼び出し元のアプリケーション ドメインに渡します。コピーが呼び出し元のアプリケーション ドメインに渡された後は、そのコピーへの呼び出しはそのコピーに対して直接実行されます。また、引数として渡された MBV オブジェクトも値によって渡されます。アプリケーションまたはコンテキストの境界を越えてクラスのインスタンスを値によって渡すために実行する必要があるのは、SerializableAttribute 属性の宣言、または ISerializable の実装のみです。

h8f0y3fc.note(ja-jp,VS.100).gif注 :
.NET Framework のバージョン 1.1 以降では、リモート処理インフラストラクチャによるサーバー上での特定の型の逆シリアル化が自動的には実行されません。アプリケーションが渡そうとする型が自動的にシリアル化されない型である場合は、サーバーの逆シリアル化のレベルを Full に設定して、サーバーが逆シリアル化を行い、MBV オブジェクトを使用できるようにする必要があります。詳細については、「.NET リモート処理での自動逆シリアル化」を参照してください。

MBV オブジェクトは、オブジェクトや実行できる機能の完全な状態をターゲットのアプリケーション ドメインに移動することが、パフォーマンスや処理上の理由から合理的であると考えられる場合に使用します。多くのシナリオでは、これによってネットワーク、プロセス、およびアプリケーション ドメインの間での往復を減らし、そのような往復にかかる多大な時間とリソースを節約することができます。MBV オブジェクトは、オブジェクトの作成元であるアプリケーション ドメインから直接使用することもできます。この場合は、マーシャリングが行われないため、コピーも作成されず、アクセス効率が向上します。

既に ISerializable が実装されているクラスを拡張する場合以外は、SerializableAttribute を使用して値渡しのマーシャリング型を作成します。この場合、型に対して ISerializable を実装する必要があります。

リモート処理システムでは、シリアル化可能なオブジェクトが頻繁に利用されます。リモート処理システムで ObjRef クラスによって表される、別のアプリケーション ドメインのオブジェクトへの参照は、参照自体がシリアル化可能です。リモート処理システムは、その正確なコピーを作成してクライアントに送信できる必要があります。また、データを転送するオブジェクトも、多くの場合シリアル化できるオブジェクトです。たとえば、DataSet は、ISerializable を実装した MarshalByValueComponent を拡張します。

ユーザー定義例外のリモート処理

システム定義の例外は、すべて値渡しのマーシャリング型であり、ISerializable インターフェイスを実装しています。リモート オブジェクトがこの例外をスローするとき、リモート処理の構成で許可されていれば、例外は自動的に呼び出し元にコピーされます。.NET Framework のバージョン 1.1 以降では、例外を呼び出し元に送る機能を有効にするには、<customErrors> 要素を off に設定する必要があります。

リモート オブジェクトによってスローされ、リモート呼び出し元によってキャッチできる例外の種類を作成する方法の詳細については、「方法 : リモート オブジェクトからスローできる例外の種類を作成する」を参照してください。

参照渡しのマーシャリング オブジェクト

参照渡しのマーシャリング (MBR: Marshal-By-Reference) オブジェクトはリモート処理可能オブジェクトであり、少なくとも System.MarshalByRefObject を拡張します。クライアントが独自のアプリケーション ドメインで MBR オブジェクトのインスタンスを作成すると、宣言されているアクティベーションの種類に応じて .NET リモート処理インフラストラクチャがその MBR オブジェクトを表すプロキシを作成し、そのプロキシに対する参照を呼び出し元に返します。次に、クライアントはプロキシの呼び出しを実行します。.NET リモート処理はこれらの呼び出しをリモート オブジェクトのアプリケーション ドメインにマーシャリングし、呼び出しを行います。

h8f0y3fc.note(ja-jp,VS.100).gif注 :
クライアントが MBR オブジェクトと同じアプリケーション ドメインにある場合、インフラストラクチャは MBR オブジェクトに対する直接の参照をクライアントに返し、マーシャリングのオーバーヘッドの発生を防ぎます。

System.MarshalByRefObject は、パラメーターとして渡された場合は、呼び出しを受信すると別のアプリケーション ドメインでプロキシとなります。MBR の戻り値と out パラメーターは、同様に機能します。

h8f0y3fc.note(ja-jp,VS.100).gif注 :
.NET Framework のバージョン 1.1 以降では、.NET リモート処理インフラストラクチャによるサーバー上での特定の型の逆シリアル化が自動的には実行されません。たとえば、パラメーターとして渡される MBR オブジェクトがサポートされるようにするには、サーバーの逆シリアル化のレベルを Full に設定して、サーバーが逆シリアル化を行い、MBR パラメーターを使用できるようにする必要があります。詳細については、「.NET リモート処理での自動逆シリアル化」を参照してください。

MBR オブジェクトを使用するのは、オブジェクトや実行できる機能の状態を作成元のアプリケーション ドメイン内にとどめておく必要があるときです。たとえば、オペレーティング システム ハンドルとして使用する内部フィールドを持つオブジェクトは、System.MarshalByRefObject を拡張する必要があります。これは、オペレーティング システム ハンドルが、他のプロセスやコンピューター内の他のアプリケーション ドメインでは意味を持たないためです。また、オブジェクトが極端に大きい場合、堅牢なサーバー上では正常に機能しても、回線を通して 33.6 Kbps モデムに送信された場合は機能しない可能性があります。

コンテキスト バインド オブジェクト

コンテキスト バインド オブジェクトは、System.ContextBoundObject を継承する MBR オブジェクトです。System.ContextBoundObject 自体は System.MarshalByRefObject を継承します。コンテキストは、その内部にあるオブジェクトに対して実行時に高度な環境を提供する、アプリケーション ドメインの下位概念と考えることができます。たとえば、コンテキストは、オブジェクトが同時に複数のスレッドからアクセスされないことを保証できます。すべてのアプリケーション ドメインには既定のコンテキストがあります。ほとんどのマネージ コードは、同じアプリケーション ドメイン内でそのドメインの既定のコンテキストを使用してオブジェクトを作成したり、メンバーを直接呼び出したりするため、コンテキストに関連する問題が発生することはありません。System.ContextBoundObject から継承されたすべての型は、同じドメイン内または他のドメイン内にある他のコンテキストに対して、プロキシとして公開されます。

たとえば、ある型にメソッドがあり、このメソッドはトランザクションの一部であるため、それが作成されたコンテキスト固有の規則による制限を受けているとします。オブジェクトがそれ自体のコンテキストからアクセスされ、システムがそのオブジェクトとメソッドに関連付けられているトランザクションに対して規則を適用できるようにするには、この型を System.ContextBoundObject から継承する必要があります。System.ContextBoundObject が同じアプリケーション ドメインにある別のコンテキストから呼び出されると、呼び出し元に対してプロキシが作成されますが、コンテキスト間の通信はチャネル システムを経由しないため、この状況での呼び出しの効率が向上します。

各境界を越えるには処理時間が必要なため、サーバーをリモート処理可能オブジェクトのどの型にするのかを決める前に、オブジェクトが越える境界を特定する必要があります。特定のコンテキストに固有のオブジェクトへは、そのコンテキストからのみ直接アクセスできます。特定のアプリケーション ドメインに固有のオブジェクトにも同じことが当てはまります。いずれかのオブジェクトをリモート処理するには、オブジェクト固有の境界の内部からサーバー オブジェクトを呼び出す前に、リモート処理システムがコンテキスト境界とアプリケーション境界のいずれか、または両方を正常に越える必要があります。オブジェクトを呼び出すときにコンテキストのチェックが不要な場合は、リモート型で System.ContextBoundObject を拡張しないようにする必要があります。この場合には、System.MarshalByRefObject の方が、パフォーマンスが優れています。コンテキストのチェックが必要な場合は System.ContextBoundObject を拡張する必要がありますが、オブジェクトに対する呼び出しが行われる前に追加の境界を越える必要があります。

公開のスコープ

それぞれのリモート処理システムには、リモートで使用できるメンバーとメンバーの型の種類を決定する固有の方法があります。.NET リモート処理は他のアプリケーション ドメインに対してオブジェクトをローカルであるかのように公開しますが、次に示す例外もあります。

  • 静的メンバー

    静的フィールドと静的メソッドはリモート処理されることがないため、フィールドへのアクセスは直接メモリを通じて行われます。つまり、.NET リモート処理では、常に一定の形式のインスタンス メンバーを処理します。

  • インスタンス フィールドとアクセサー

    インスタンス フィールドおよびアクセサー メソッドの場合は、実行時にシステムによってオブジェクトがプロキシかどうかのチェックが行われます。オブジェクトがプロキシでない場合、フィールドへのアクセスは直接アクセスになります。それ以外の場合、プロキシは呼び出し元にアクセサーを提供します。

  • プライベート メソッド

    プライベート メソッドはリモート処理できません。デリゲートをリモートでラップしてプライベート メソッドに渡すことはできません。

  • デリゲート

    デリゲートは値渡しのマーシャリング オブジェクトです。デリゲート内のオブジェクトとしては、任意の種類のリモート処理可能オブジェクト (シリアル化できるオブジェクト、MarshalByRefObject オブジェクト、または ContextBoundObject オブジェクト) が考えられます。ただ 1 つの例外は、インターフェイス メソッドへのデリゲートは正常にリモート処理されないことです。このデリゲートはインターフェイス メソッドの実装をラップするため、クライアントの型情報をサーバーで利用できることが必要条件となります。

  • Object のメソッドのオーバーライド

    パフォーマンス上の理由から、Object の仮想メソッドは、呼び出し元のアプリケーション ドメインで常にローカルで実行されます。次に示すメソッドがリモート オブジェクトでオーバーライドされている場合、これらのメソッドに対する呼び出しは、リモート オブジェクトに対してのみ行われます。

    • Equals

      この仮想メソッドがオーバーライドされている場合はリモートで実行されます。

    • GetHashCode

      このメソッドはローカルで実行されます。

    • ToString

      この仮想メソッドがオーバーライドされている場合はリモートで実行されます。

    • Equals (静的バージョン)

      このメソッドはローカルで実行されます。

    • MemberwiseClone

      このメソッドはローカルで実行されます。

参照

処理手順

方法 : リモート オブジェクトからスローできる例外の種類を作成する

その他のリソース

.NET Framework リモート処理の概要
オブジェクトをリモート処理可能にする