Condividi tramite


Oggetti remotizzabili e non remotizzabili

È importante ricordare che un oggetto creato in un dominio di applicazione e pertanto specifico dello stesso può essere chiamato direttamente da tale dominio, mentre per rendere tale oggetto disponibile all'esterno del proprio dominio è necessario eseguire alcune operazioni speciali. Poiché non tutti i tipi di oggetto possono essere pubblicati o utilizzati in modo efficiente oltre i limiti dei domini, è necessario decidere quale tipo di oggetto si desidera pubblicare in base alle esigenze dell'applicazione. Ai fini delle applicazioni distribuite, sono disponibili due categorie di oggetti, ovvero gli oggetti non remotizzabili e remotizzabili.

Oggetti non remotizzabili

Alcuni oggetti non possono essere utilizzati all'esterno del proprio dominio di applicazione. Su tali oggetti non viene mai eseguito il marshalling poiché non dichiarano un metodo di serializzazione. Questi oggetti sono progettati per essere impiegati all'interno dello stesso dominio di applicazione in cui sono stati creati. L'accesso a tali oggetti viene sempre eseguito direttamente dal dominio di applicazione specifico. La maggior parte delle classi nella libreria di classi di .NET Framework è costituita da oggetti non remotizzabili. Gli oggetti non remotizzabili non possono essere copiati o rappresentati in un altro dominio di applicazione, ma sono accessibili unicamente dal dominio di applicazione originale.

Oggetti remotizzabili

È possibile accedere agli oggetti remotizzabili dall'esterno del relativo dominio di applicazione o contesto mediante un proxy, nonché copiarli e passare la copia all'esterno del relativo dominio di applicazione o contesto. In altre parole, alcuni oggetti remotizzabili vengono passati per riferimento, altri per valore.

Tali oggetti funzionano perfettamente in un ambiente ampiamente distribuito. Esistono due tipi principali di oggetti remotizzabili:

  • Oggetti con marshalling per valore, che vengono copiati e passati all'esterno del dominio di applicazione.

  • Oggetti con marshalling per riferimento, per i quali viene creato un proxy utilizzato dal client per accedere all'oggetto in modalità remota.

Oggetti con marshalling per valore

Gli oggetti con marshalling per valore (MBV, Marshal-by-value) dichiarano le regole di serializzazione mediante l'implementazione dell'interfaccia ISerializable per la propria serializzazione o mediante la decorazione con l'attributo SerializableAttribute, che comunica al sistema di serializzare l'oggetto automaticamente, ma non estendono oggetti MarshalByRefObject. Il sistema .NET Remoting crea una copia completa di questi oggetti e la passa al dominio di applicazione che esegue la chiamata. Una volta che la copia si trova nel dominio di applicazione del chiamante, le chiamate vengono indirizzate direttamente a quella copia. Inoltre, gli oggetti MBV passati come argomenti vengono passati anche per valore. Oltre alla dichiarazione dell'attributo SerializableAttribute o all'implementazione dell'interfaccia ISerializable, non è necessario eseguire altre operazioni per passare le istanze della classe per valore oltre i limiti dell'applicazione o del contesto.

Nota

A partire dalla versione 1.1 di .NET Framework, nell'infrastruttura di .NET Remoting non vengono deserializzati automaticamente alcuni tipi sul server. Se in uno scenario specifico si verifica tale situazione, è necessario impostare il livello di deserializzazione del server su Full prima che il server sia in grado di deserializzare e utilizzare un oggetto MBV. Per ulteriori informazioni, vedere Deserializzazione automatica in .NET Framework Remoting.

È opportuno utilizzare gli oggetti MBV quando, per ragioni di prestazioni o elaborazione, è preferibile spostare lo stato completo dell'oggetto e qualsiasi funzionalità eseguibile nel dominio di applicazione di destinazione. In molti scenari questa soluzione riduce i lunghi percorsi di andata e ritorno, di lunghezza elevata e che richiedono un utilizzo intenso delle risorse, oltre i limiti di rete, di processi e di domini di applicazione. Gli oggetti MBV vengono anche utilizzati direttamente dall'interno del dominio di applicazione originale dell'oggetto. In questo caso, poiché non viene eseguito il marshalling, non vengono create copie e l'accesso è estremamente efficiente.

Se le dimensioni degli oggetti pubblicati sono elevate, tuttavia, il passaggio di una copia intera su una rete occupata può rivelarsi una scelta errata. Le modifiche apportate allo stato dell'oggetto copiato, inoltre, non vengono mai comunicate all'oggetto di origine nel dominio di applicazione originale. A un livello astratto, questo scenario è simile a quello di una pagina HTML statica richiesta da un browser client. Il file viene copiato, scritto in un flusso, inviato, quindi dimenticato dal server. Qualsiasi richiesta successiva è semplicemente una richiesta di un'altra copia.

Per creare un tipo con marshalling per valore, è possibile utilizzare l'attributo SerializableAttribute a meno che non venga estesa una classe che implementa già l'interfaccia ISerializable. In questo caso, è necessario implementare l'interfaccia ISerializable per il tipo specifico.

Nel sistema .NET Remoting vengono ampiamente utilizzati gli oggetti serializzabili. Un riferimento a un oggetto in un altro dominio di applicazione, rappresentato nel sistema .NET Remoting dalla classe ObjRef, è serializzabile ed è possibile copiarlo esattamente e inviarne la copia a una richiesta. Analogamente, è possibile eseguire le stesse operazioni per gli oggetti messaggio che implementano IMessage, poiché sono contenitori generici di informazioni sulle chiamate e di altri riferimenti necessari agli oggetti. Gli oggetti che trasferiscono semplicemente i dati, inoltre, sono spesso serializzabili. L'oggetto DataSet, ad esempio, estende MarshalByValueComponent, che implementa l'interfaccia ISerializable.

Eccezioni definite dall'utente nel sistema .NET Remoting

Le eccezioni definite dal sistema sono tutti tipi con marshalling per valore che implementano l'interfaccia ISerializable. Se generate da un oggetto remoto, vengono copiate automaticamente nel chiamante se le configurazioni del sistema .NET Remoting lo consentono. A partire dalla versione 1.1 di .NET Framework, per attivare il passaggio delle eccezioni al chiamante, l'elemento <customErrors> deve essere impostato su off.

Per ulteriori informazioni sulla creazione di un tipo di eccezione che può essere generata da un oggetto remoto e intercettata da un chiamante remoto, vedere Procedura: creare un tipo di eccezione generabile da oggetti remoti

Oggetti con marshalling per riferimento

Gli oggetti con marshalling per riferimento (MBR, Marshal-by-reference) sono oggetti remotizzabili che estendono almeno un oggetto System.MarshalByRefObject. A seconda del tipo di attivazione dichiarato, quando un client crea un'istanza di un oggetto MBR nel dominio di applicazione di appartenenza, dall'infrastruttura di .NET Remoting viene creato un oggetto proxy nel dominio di applicazione del chiamante che rappresenta l'oggetto MBR e restituisce al chiamante un riferimento a tale proxy. Il client esegue quindi le chiamate sul proxy. Il sistema .NET Remoting esegue il marshalling di tali chiamate, le invia al dominio di applicazione di origine e le esegue nuovamente sull'oggetto effettivo.

Nota

Se il client si trova nello stesso dominio di applicazione dell'oggetto MBR, l'infrastruttura restituisce al client un riferimento diretto all'oggetto MBR, evitando in questo modo di causare un sovraccarico per l'operazione di marshalling.

Se un oggetto MarshalByRefObject viene passato come parametro, quando arriva la chiamata tale oggetto diventa un proxy. Il funzionamento dei valori restituiti MBR e dei parametri out è analogo.

Nota

A partire dalla versione 1.1 di .NET Framework, nell'infrastruttura di .NET Remoting non vengono deserializzati automaticamente alcuni tipi sul server. Per ottenere supporto per gli oggetti MBR passati come parametri, ad esempio, è necessario impostare il livello di deserializzazione del server su Full prima che il server sia in grado di deserializzare e utilizzare il parametro MBR. Per ulteriori informazioni, vedere Deserializzazione automatica in .NET Framework Remoting.

Utilizzare gli oggetti MBR quando è necessario che stato dell'oggetto ed eventuali funzionalità eseguibili rimangano nel dominio di applicazione in cui sono stati creati. È necessario, ad esempio, che un oggetto in cui un campo interno è un handle del sistema operativo estenda MarshalByRefObject, poiché l'handle non avrebbe significato in un altro dominio di applicazione, in un altro processo o in un altro computer. Talvolta le dimensioni di un oggetto possono essere eccessive per essere inviate tramite una connessione a un modem da 33,6 KBps, benché non creino problemi su un server potente.

Oggetti associati al contesto

Gli oggetti associati al contesto sono oggetti MBR che ereditano da System.ContextBoundObject, che a sua volta eredita da System.MarshalByRefObject. Per contesto si intende una suddivisione di un dominio di applicazione in cui è implementato un ambiente completo per gli oggetti presenti durante l'esecuzione. Un contesto può garantire, ad esempio, che non sia possibile accedere all'oggetto contemporaneamente da più thread. Ogni dominio di applicazione dispone di un contesto predefinito. Nella maggior parte del codice gestito gli oggetti vengono creati e i membri chiamati direttamente dall'interno dello stesso dominio di applicazione mediante tale contesto predefinito, senza che si verifichino problemi relativi al contesto stesso.. Tutti i tipi che ereditano da ContextBoundObject sono esposti come proxy ad altri contesti, appartenenti o meno allo stesso dominio.

Si supponga, ad esempio, di disporre di un metodo su un tipo che fa parte di una transazione e associato, di conseguenza, in base alle regole specifiche del contesto in cui è stato creato. È necessario che tale tipo erediti da ContextBoundObject, in modo che l'accesso all'oggetto avvenga dal contesto dell'oggetto stesso e che possano essere attivate le regole inerenti alle transazioni associate a tale oggetto e ai relativi metodi. Se un oggetto ContextBoundObject viene chiamato da un altro contesto all'interno dello stesso dominio di applicazione, viene creato un proxy per il chiamante, ma la comunicazione intercontesto non consente di attraversare il sistema del canale, determinando un incremento dell'efficienza della chiamata in una situazione di questo tipo.

Poiché l'operazione precedente richiede un determinato tempo di elaborazione, è utile stabilire i limiti che l'oggetto deve attraversare per decidere a quale tipo di oggetto remotizzabile il server dovrà corrispondere. È possibile accedere direttamente agli oggetti specifici di un determinato contesto o dominio di applicazione solo dal contesto o dal dominio di applicazione specifico. Per utilizzare in modalità remota uno di questi oggetti, il sistema .NET Remoting deve essere in grado di attraversare un limite di contesto, un limite di applicazione o entrambi prima di chiamare l'oggetto server dall'interno del limite di cui è specifico. Se non è necessario un controllo di contesto per chiamare l'oggetto, è consigliabile evitare che il tipo remoto estenda ContextBoundObject. In questo modo l'oggetto MarshalByRefObject è in grado di offrire prestazioni migliori. Se invece il controllo di contesto è necessario, ContextBoundObject deve essere esteso. In questo caso è necessario tenere presente che, prima di eseguire la chiamata sull'oggetto, il limite aggiuntivo deve essere attraversato.

Ambito della pubblicazione

Nei diversi sistemi di interazione remota i membri e i tipi di membro da utilizzare in modalità remota vengono stabiliti in modo diversi.. In .NET Remoting gli oggetti vengono esposti ad altri domini di applicazione come se fossero locali, con le seguenti eccezioni:

  • Membri statici

    Campi e metodi statici non vengono mai utilizzati in modalità remota e l'accesso ai campi avviene tramite la memoria in modo diretto. Questo significa che in .NET Remoting vengono sempre gestiti membri di istanza di qualche tipo.

  • Campi di istanza e funzioni di accesso

    Per i campi di istanza e i metodi della funzione di accesso, viene inserito un controllo in fase di esecuzione per verificare se l'oggetto è un proxy. Se l'oggetto non è un proxy, l'accesso ai campi è diretto. In caso contrario, il proxy fornisce funzioni di accesso al chiamante.

  • Metodi Private

    Non è possibile utilizzare i metodi Private né eseguire il wrapping di un delegato e passarlo a un metodo Private in modalità remota.

  • Delegati

    I delegati sono oggetti con marshalling per valore. L'oggetto all'interno del delegato può essere qualsiasi oggetto remotizzabile, ad esempio un oggetto serializzabile, un oggetto MarshalByRefObject o un oggetto ContextBoundObject. L'unica eccezione è rappresentata dal fatto che non è possibile utilizzare correttamente un delegato su un metodo di interfaccia in modalità remota. Il delegato eseguirà il wrapping dell'implementazione del metodo di interfaccia, richiedendo che le informazioni sul tipo del client siano disponibili per il server.

  • Esecuzione dell'override dei metodi su Object 

    Per motivi relativi alle prestazioni, i metodi virtuali su metodi Object vengono sempre eseguiti localmente nel dominio di applicazione in cui sono chiamati. Le chiamate dei metodi seguenti vengono passate all'oggetto remoto soltanto quando i metodi sono stati sottoposto a override su tale oggetto:

    • Equals 

      Metodo virtuale eseguito in modalità remota se sottoposto a override.

    • GetHashCode 

      Metodo viene eseguito localmente.

    • ToString 

      Metodo virtuale eseguito in modalità remota se sottoposto a override.

    • Equals (versione statica)

      Metodo viene eseguito localmente.

    • MemberwiseClone 

      Metodo viene eseguito localmente.

Vedere anche

Attività

Procedura: creare un tipo di eccezione generabile da oggetti remoti

Altre risorse

Cenni preliminari su .NET Framework Remoting
Trasformazione in oggetti remotizzabili