Question

J'ai un MarshalByRefObject que je devais serialize et stocker (dans une base de données), afin que je puisse désérialiser et référencer plus tard. Je l'ai choisi d'adopter une approche différente: en ce moment, je suis en cours d'exécution d'un service Windows qui maintient simplement (s'il vous plaît noter que le MarshalByRefObjects est en fait un objet 3ème partie, que je ne me crée pas) RemoteObject « vivant »:

// This is the object which extends the MarshalByRefObject class
RemoteObject myRemoteObject = new RemoteObject;

TcpServerChannel channel = new TcpServerChannel(6789);
ChannelServices.RegisterChannel(channel, true);

ObjRef objRef = RemotingServices.Marshal((System.MarshalByRefObject)myRemoteObject, id);

Dans un autre AppDomain je vous suffit de connecter et de récupérer l'objet; tout va bien de travaux:

RemoteObject myLocalObject = (FCEngine.IFCVerificationSession)Activator.GetObject(
                           typeof(FCEngine.IFCVerificationSession),"tcp://localhost:6789/" + id);

Maintenant, le problème est que le RemoteObject contient une propriété qui est simplement une poignée de HBITMAP casté en type long. Je peux récupérer la poignée facilement. Normalement (localement) je le ferais:

IntPtr hbitmap = (IntPtr)myLocalObject.ContextImage;
System.Drawing.Bitmap bmp = System.Drawing.Image.FromHbitmap(hbitmap);

Cela ne fonctionne pas dans le cas présent. Je reçois un System.Runtime.InteropServices.ExternalException Je suppose que le problème est que hbitmap est une poignée à une mémoire qui n'existe pas dans le AppDomain local, mais dans le service Windows AppDomain. Ma question est ce que mes options sont:

  • Le RemoteObject est assez complexe, il est comme un arbre dans lequel on traverse les noeuds en appelant ses fonctions. Les impose 3ème partie que je ne peux traverser l'objet une fois. Donc, le traversant service côté, le stockage bitmaps dans une base de données, et le parcourir à distance à nouveau ne fonctionnera pas.
  • idéal serait de pouvoir appeler une fonction dans le service Windows et passer la poignée de HBITMAP comme argument, renvoyant le bitmap réel. Ceci est impossible dans les services Windows.
  • je pouvais stocker la poignée dans une base de données et faire le sondage service Windows la base de données pour cela. Il pourrait alors récupérer le bitmap et le stocker dans le même DB pour moi. Je pourrais alors à nouveau récupérer ce bitmap à distance. Ceci est très laid, puisque j'ai besoin immédiatement le bitmap.

En fait, je voudrais savoir si vous avez des suggestions pour ne pas avoir à effectuer hacks laides comme la 3ème option ... Quelles sont mes options?

RESOLU En ce moment, j'ai résolu le problème en créant un objet personnalisé qui s'étend MarshalByRefObject sur le côté service. Cet objet a une méthode pour récupérer et enregistrer un bitmap en passant la poignée. J'approche simplement l'objet à distance, de la même manière que j'approche de mon objet 3ème partie. Trop simple, d'une solution, même si un collègue a dû le signaler.

Était-ce utile?

La solution

HBitmap est une poignée, il n'a pas de sens de sérialisation poignées non gérés. Vous devez sérialiser le contenu bitmap, recréer (bitmap) sur un côté distant, puis réattribuer HBITMAP nouvellement créé.

P.S. Physiquement poignée est un pointeur vers pointeur, sa valeur est applicable uniquement un espace d'adressage est a été créé.

à mon humble avis.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top