シリアル化して(データベースに)保存する必要があるMarshalByRefObject
ものがあるので、後で逆シリアル化して参照することができます。私はこれに別の方法でアプローチすることを選択しました。現在、単に「生きている」状態を維持するWindowsサービスを実行しています(これは実際にはサードパーティのオブジェクトであり、自分で作成したものではないことにMarshalByRefObjects
注意してください)。RemoteObject
// 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);
別のAppDomainでは、オブジェクトを接続して取得するだけです。すべて正常に動作します:
RemoteObject myLocalObject = (FCEngine.IFCVerificationSession)Activator.GetObject(
typeof(FCEngine.IFCVerificationSession),"tcp://localhost:6789/" + id);
ここで問題となるのは、が型にキャストされたRemoteObject
単なるHBITMAP
ハンドルであるプロパティを含んでいることlong
です。ハンドルを簡単に取り出せます。通常(ローカルで)私はします:
IntPtr hbitmap = (IntPtr)myLocalObject.ContextImage;
System.Drawing.Bitmap bmp = System.Drawing.Image.FromHbitmap(hbitmap);
現在の場合、これは機能しません。問題は、ローカルのAppDomainには存在しないが、WindowsサービスのAppDomainには存在しないメモリへのハンドルであるSystem.Runtime.InteropServices.ExternalException
と思います。hbitmap
私の質問は私のオプションが何であるかです:
- これ
RemoteObject
はかなり複雑で、関数を呼び出してノードをトラバースするツリーのようなものです。サードパーティは、オブジェクトを1回しかトラバースできないことを強制します。したがって、サービス側でトラバースし、データベースにビットマップを格納し、リモートで再度トラバースすることは機能しません。 - 理想的なのは、Windowsサービスで関数を呼び出し、hbitmapハンドルを引数として渡して、実際のビットマップを返すことができることです。これは、Windowsサービスでは不可能です。
- ハンドルをデータベースに保存し、Windowsサービスでデータベースをポーリングすることができます。次に、ビットマップを取得して、同じDBに保存できます。その後、そのビットマップをリモートで再度取得できます。ビットマップがすぐに必要なので、これは非常に醜いです。
基本的に、3番目のオプションのような醜いハックを実行する必要がないという提案があるかどうか知りたいです...私のオプションは何ですか?
解決済み現在、サービス側でMarshalByRefObjectを拡張するカスタムオブジェクトを作成することで問題を解決しました。このオブジェクトには、ハンドルを渡すことによってビットマップを取得して保存するメソッドがあります。サードパーティのオブジェクトにアプローチするのと同じ方法で、オブジェクトにリモートでアプローチするだけです。同僚がそれを指摘しなければならなかったが、解決策は単純すぎる。