Serializable funktioniert nicht, nur MarshalByRefObject

14/02/2009 - 21:54 von Peter Holschbach | Report spam
Hallo,

ich muß ein Assembly in einer anderen AppDomain laden damit es spàter wieder
entladen werden kann. Zischen meiner Applikation un dem Assembly müssen
Daten augetauscht werden. Wenn ich alles richtig verstanden habe, dann
müssen die verwendeten Typen entweder das Attribut Serializable haben oder
vom Typ MarshalByRefObject abgeleitet sein.
Leider funktioniert die erste Methode nicht:

[Serializable]
public class MyClass
{
public void Execute()
{
Console.WriteLine("Hallo");
}
}

führt immer zu eine SerializationException.

Verwende ich

Serializable]
public class MyClass : MarshalByRefObject
{
public void Execute()
{
Console.WriteLine("Hallo");
}
}


dann funktioniert es.
Leider kann ich nicht alle notwendigen Klassen von MarshalByRefObject
ableiten.
Was kann man mit dem Attribut Serializable denn falsch machen ?
Hat da jemand eine Idee ?

thx
Peter
 

Lesen sie die antworten

#1 Frank Dzaebel
15/02/2009 - 13:45 | Warnen spam
Hallo Peter,

Wenn ich alles richtig verstanden habe, dann müssen die verwendeten Typen
entweder das Attribut Serializable haben oder vom Typ MarshalByRefObject
abgeleitet sein.



Es gibt ein:
"Marshal by Reference [MBR]" ->MarshalByRefObject
und ein:
"Marshal by Value [MBV]" ->[Serializeble]

Damit Verweis-Remoting für eine bestimmte Klasse funktioniert, darf die
Klasse nur eine einzige Sache tun, nàmlich von MarshalByRefObject erben.
"Bekannten Objekte" (serveraktivierte Objekte) *müssen* von der
MarshalByRefObject-Klasse abgeleitet werden!

[Chapter 11 - Improving Remoting Performance]
http://msdn.microsoft.com/en-us/lib...11_topic14

Ich kopiere hier noch eine IMHO ~gelungene Beschreibung aus einer Newsgroup:

<Zitat> :

If you want to access an object in the server - that is to activate its
methods and properties you must inherit the class from MarshalByRefObject.
This is because in the client you only have a refernce to that object and
a
proxy is created for you.
However, sometimes you just want to pass information between the server
and
the client in the form of objects. This objects will be serialized sent to
the other process (maybe other computer) and de-serialized in the remote
process. All the internal information in these kinds of objects is passed,
and each method and property you call in the remote process is done in
that
process. For this kind of behavior you must either set the Serializable
attribute, or implement the ISerializable interface.

So how can you pass an object by value between the server and the client?
You need one object in the server to inherit from MarshalByRefObject with
a
method that returns the Serializable object, or that get a Serializable
object as parameter, That way objects are passed by value between the
client
and the server. [...]

Now that the issue of MarshalByRef and Marshal by value is settled, lets
investigate the "the server can forget all about it " issue, or in other
words Stateless objects. There are two types of ways the client can use
Remote objects (marshaled by reference). Singleton or SingleCall. The
first
will create one instance that all the clients call. This object will be
with
state that will be kept between calls. The second will act as a service -
It
does not remember state between call, each time a client tries to call a
method or property it calls a new instance in the server.

Ok, now I will explain what shared assemblies are all about. In order for
an
object to be called in remotely, and it does not matter whether it is
marshaled by reference or serializable, both client and server must know
of
this object. Why? simply because the client (for example) can't access
class
X's method without it having a definition for the class and method. This
is
very understandable, and it doesn't work in the way you have described. So
what we need is to have a dll (class library) with all the common objects
to
both server and clients - all the MarshalByReference and Serializable
objects should be in that assembly. Both Server and Client executables
should have a reference to that dll.

But this is very bad. We don't want the client to have the implementation
of
the server's objects and the other way around. That's when interfaces come
to the rescue. In the shared assembly we will put only interfaces and
classes that it is ok to share. The client and server will only know of
this
interfaces. The actual classes which implement the interfaces will be in
the
client/server assemblies, but the other will not know of them. I hope this
is clear. So we don't need to deploy server classes in the client - just a
dll with interface which is also deployed with the server.

<Zitat Ende>


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen