2016-09-28 25 views
1

对于我的项目,我需要从其他.Net程序集访问资源,但我不想让它们保持加载状态,因为我可能会加载相同程序集的不同版本。将代理对象克隆到当前AppDomain中

因此,为了做到这一点,我创建了另一个使用CreateInstanceAndUnwrap创建从MarshalByRefObject下降的自定义类的AppDomain。在那个类中我加载了程序集,它有一个返回资源对象(字符串,位图等)的函数。

现在的问题是,在临时AppDomain被卸载后(除了像结构体这样的值类型对象除外),我无法保留对这些对象的引用,所以抛出了AppDomainUnloadedException。

那么是否有可能将从另一个AppDomain获得的对象复制到当前AppDomain中,知道这些对象都可能是Serializable或实现ISerializable?

可能很重要的一点是,Bitmap继承自MarshalByRefObject,实现ISerializable并具有Seri​​alizable属性。这是一个小小的片段来演示这个问题。

class ImageGrabber : MarshalByRefObject 
{ 
    public Image GetImage() { return new Bitmap(16,16); } 
} 

//testing 
var tmpDomain = AppDomain.CreateDomain("test"); 
var proxy = (ImageGrabber)tmpDomain.CreateInstanceAndUnwrap(
    typeof(ImageGrabber).Assembly.FullName, 
    typeof(ImageGrabber).FullName); 
Bitmap myImage = proxy.GetImage(); 
AppDomain.Unload(tmpDomain); 
pictureBox.Image = myImage;//throws AppDomainUnloadedException 

回答

0

看起来像位图不喜欢被序列化......它的许多属性都是类型未标记为可序列化,即使Save方法也不起作用,因为它必须使用代理对象无法序列化的属性。所以我别无选择,只能在运行临时AppDomain的代码中将图像转换为流(或字节数组也可以)。

然后,该流仍然附加到AppDomain,但幸好流类型序列化没有困难,所以我可以将它复制到MemoryStream中。

0

在这种特定的情况下,你可以使用System.Drawing.ImageConverter

var myImage = proxy.GetImage(); 

var converter = new ImageConverter(); 
var data = (byte[])converter.ConvertTo(myImage, typeof(byte[]); 

AppDomain.Unload(tmpDomain); 
pictureBox.Image = (Bitmap)converter.ConvertFrom(data); 

注意:你的问题的代码,我不认为这编译,顺便说一句:

Bitmap myImage = proxy.GetImage(); 

“HTH ,