请教 跨Appdomain传值 的问题

间谍 2010-09-17 05:58:01
.net via c#中有处不理解,水平比较菜,可能没问到点子上,请大家帮忙。

书中600页左右有个Accessing Objects Across AppDomain Boundaries的例子,大概流程这样:
1. 在当前Appdomain AD#1中创建一个新的Appdomain AD#2
2. 在AD #2中加载一个Assembly S,创建类 C
3. AD#1得到一个Marshaled-by-reference的远程的引用 r
4. 调用这个AD#1中r调用AD#2的函数fun,返回一个marshaled-by-val的引用r2,指向一个从AD#2的S被序列化到AD#1中的C2

按书中说法,第4步之后,因为需要meta信息,AD#1中也会加载S,而assembly是不能卸载的,这样的话在上述步骤后卸载掉AD#2后与下面的做法有什么区别呢?
1. 在当前Appdomain AD#1中加载S
2. 创建类C2

如果没有区别的话,是不是说*在本机appdomain间以书中例子为目的*做by val是没意义的呢?这种手段的具体应用场合有些什么呢?感謝大家。
...全文
240 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
间谍 2010-09-17
  • 打赏
  • 举报
回复
问题简化一下,其实是两个问题。

首先,比如我有两个Assembly,分别是Main和Plugin

现在我想让Main动态的加载Plugin,在Plugin中生成类,调用方法,而且可以随时卸载。

最简单的我想是在Main直接加载Plugin,但.Net不支持卸载Assembly(?),这样就无法实现我随时卸载的需求。

然后我自然就想到创建一个新的Appdomain,然后用新的appdomain加载Plugin,然后从Main访问新appdomain中的类,不需要的时候只要卸掉那个appdomain。但因为Main所在的appdomain在调用时需要关于plugin的metadata,所以clr又要把plugin加载到main所在的appdomain中,这样的话就达不到我想要的了,这样的情况下,我应该怎么办?(第一个疑問)

通过这个问题,又引出我主题里的疑問,那个by val方式在本机的appdomaiin之间应用时有意义吗?为什么不直接加载class所在的assembly呢?(第二个疑問)
sxmonsy 2010-09-17
  • 打赏
  • 举报
回复
这个没用过,友情UP下。
glest 2010-09-17
  • 打赏
  • 举报
回复
一个应用程序域可以通过两种方式和另一个应用程序域进行通信。一种是传值(by value),另一种是传引用(by reference)
传值是通过对象的序列和反序列实现的,因此要传递的对象必须有 System.Serializable属性.
它的实现原理:我们在应用程序域A中构造了一个对象A1,现在要将对象A1的引用传递给另
一个应用程序域B,CLR首先会将对象A1的字段序列化到一个内存块,然后再将这个内存块的地址
传递给另一应用程序域B,将由应用程序域B反序列化得对新的对象B1,因此这个新的对象B1应该是在
应用程序域A中。
可以通过以下代码来证实:
using System;
using System.Reflection;
using System.Threading;
using System.Runtime.Serialization;

class App {
static void Main() {
AppDomain domain = AppDomain.CreateDomain("MyNewDomain", null, null);

Test test = (Test) domain.CreateInstanceAndUnwrap(
Assembly.GetCallingAssembly().FullName, "Test");

test.TestMethod(Thread.GetDomain().FriendlyName);
AppDomain.Unload(domain);
}
}

[Serializable]
class Test// : MarshalByRefObject
{
public void TestMethod(string srcAppDomain) {
Console.WriteLine(
"Code from the '{0}' AppDomain\n" +
"called into the '{1}'. AppDomain.",
srcAppDomain, Thread.GetDomain().FriendlyName);
}
}

而传引用则能过创建代理对象来实现,传递的对象要从System.MarshalByRefObject类继承。
当对象的引用传递到另一应用程序域中时,CLR会在目的应用程序域中创建一个代理对象,
目的应用程序域中引用的将是这个代理对象,它通过代理对象来调用源应用程序域中的对象。
由于它实际上调用的还是源应用程序域中的对象,因此线程要在两个应用程序域中跳转。
(参见.NET框架程序设计(修订版)P514)可以修改上面Test类部分代码来证实:
// [Serializable]
class Test : MarshalByRefObject
KnowKjava 2010-09-17
  • 打赏
  • 举报
回复
不太明白
无涯大者 2010-09-17
  • 打赏
  • 举报
回复
好问题 还没有遇到过 路过帮忙顶下~
gomoku 2010-09-17
  • 打赏
  • 举报
回复
你的plugin不用接口吗?

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧