在.NET中,每个应用程序域都是一个独立的执行环境,有自己的安全边界和上下文。当使用AppDomain.ExecuteAssembly方法在一个新的应用程序域中执行一个程序集时,这个程序集将会在新的应用程序域中加载和执行,而与原应用程序域隔离开来,两个应用程序域之间的交互是受到限制的。

默认情况下,新应用程序域中的程序集无法访问原应用程序域中的对象和资源。如果需要在不同的应用程序域之间进行通信,需要使用.NET提供的跨应用程序域通信(Cross-AppDomain Communication)机制,例如MarshalByRefObject和AppDomain.UnhandledException事件等。

如果需要在新应用程序域中执行某些操作并将结果返回给原应用程序域,可以使用Remoting或WCF等技术。其中,Remoting提供了一种透明的远程调用机制,可以使得应用程序域之间的调用像本地调用一样简单;而WCF则提供了更加通用的跨进程和跨网络通信机制,可以支持多种协议和格式,具有更高的灵活性和扩展性。

总之,在.NET中,新的应用程序域与原应用程序域之间的交互需要通过特定的机制来实现,具体实现方式取决于具体的场景和需求.

在.NET中,被调用的目标程序集必须是可执行的,这是因为在.NET中,应用程序域的基本单元是可执行程序集(Assembly),而非单个类或对象。应用程序域是.NET提供的一种隔离机制,可以在同一个进程中加载和执行多个不同的可执行程序集,从而实现应用程序的模块化和隔离。

当在应用程序域中调用一个程序集时,CLR会将其加载到应用程序域中,并在其中创建一个或多个AppDomain对象。这个AppDomain对象将会在应用程序域的边界内隔离程序集的执行环境,保证程序集的运行不会对应用程序域之外的其他部分产生影响,从而提高应用程序的安全性和可靠性。

因此,为了能够在应用程序域中加载和执行一个程序集,这个程序集必须是可执行的,即符合.NET可执行程序集的规范,包含符号表、元数据和IL代码等信息。只有这样,CLR才能够正确地解析和执行这个程序集,并将其隔离在应用程序域内部的执行环境中,同时与其他程序集和应用程序域进行交互和通信。

总之,在.NET中,被调用的目标程序集必须是可执行的,才能够被加载到应用程序域中进行隔离和执行。

在.NET中,AppDomain类提供了一个DoCallBack方法,可以在当前应用程序域中调用指定委托(Delegate)的方法,并将其委托到另一个应用程序域中执行。这个方法通常用于实现应用程序域之间的通信和协作,可以在不同的应用程序域之间传递数据和执行代码,从而实现应用程序的分布式和模块化。

public void DoCallBack(CrossAppDomainDelegate callBackDelegate);

其中,callBackDelegate参数是一个CrossAppDomainDelegate委托,表示要在另一个应用程序域中执行的方法。该委托的参数和返回值必须是序列化和可传递的类型,否则将无法在应用程序域之间进行传递。

使用DoCallBack方法在新应用程序域中执行一个委托。这个委托输出了当前应用程序域的名称,并通过AppDomain.SetData方法将数据传递回主应用程序域。需要注意的是,在使用DoCallBack方法时,委托中的代码将会在另一个应用程序域中执行,因此需要考虑到数据和代码的传递和隔离问题。同时,由于跨应用程序域调用涉及到数据序列化和传输,因此可能会对性能和可靠性产生一定的影响。

AppDomain newDomain = AppDomain.CreateDomain("JohnYang New Domain");

            Console.WriteLine(AppDomain.CurrentDomain.FriendlyName+","+AppDomain.CurrentDomain.IsDefaultAppDomain());
newDomain.SetData("Data", "Hello in new Domain");//在新应用程序域中设置槽
newDomain.DoCallBack(() =>
{
//这些代码在newDomain中执行
Console.WriteLine($"this is in {AppDomain.CurrentDomain.FriendlyName},{AppDomain.CurrentDomain.IsDefaultAppDomain()}"); var data = AppDomain.CurrentDomain.GetData("Data");//newDomain自身设置Data
Console.WriteLine($"new domain get data:{data}");//newDomain自身获取Data
});
//主程序域获取不到该项
Console.WriteLine($"{AppDomain.CurrentDomain.FriendlyName}获取"+AppDomain.CurrentDomain.GetData("Data"));
AppDomain.Unload(newDomain);
Console.ReadLine();

output:

Learn.exe,True
this is in JohnYang New Domain,False
new domain get data:Hello in new Domain
EasyBimBackend.exe获取

以下代码证明,独立应用程序域中,每个应用程序域都有自己的内存空间和运行环境,不同的应用程序域之间相互隔离,无法直接相互访问。因此,即使是同一个类的静态成员,也不能在不同的应用程序域之间相互访问。

class ProgramA
{
public static int count;
static void Main()
{
var domain = AppDomain.CreateDomain("JohnYang new domain");
domain.DoCallBack(() =>
{
ProgramA.count = 100; });
Console.WriteLine(ProgramA.count);//打印0
Console.ReadLine();
}
}

在 MarshalByRefObject 对象之间进行远程调用时,数据流通常是单向的,即从客户端应用程序域到服务器应用程序域。但是,通过将一个 MarshalByRefObject 对象传递给另一个 MarshalByRefObject 对象的方法作为参数,可以实现远程过程调用的逆向。

具体来说,当 FooA 对象的方法接受一个 MarshalByRefObject 参数时,可以将另一个可远程访问的对象作为参数传递进来。这个参数对象在客户端应用程序域中创建,但是由于它继承自 MarshalByRefObject,所以客户端应用程序域中的代理对象将会在服务器应用程序域中创建一个真实的对象,然后将该对象作为参数传递给服务器应用程序域中的方法。

因此,逆向的 Remoting 过程是指在远程过程调用中,数据流向是从服务器应用程序域到客户端应用程序域。这使得客户端应用程序可以向服务器应用程序传递对象,从而实现更灵活和动态的交互。

public class FooA : MarshalByRefObject
{
public string SayHello(FooB b) => $"Hello from {AppDomain.CurrentDomain.FriendlyName}. FooB says: {b.SayHello()}";
} public class FooB : MarshalByRefObject
{
public string SayHello() => $"Hello from {AppDomain.CurrentDomain.FriendlyName}";
}
class ProgramA
{
static void Main()
{
AppDomain newDomainA = AppDomain.CreateDomain("new domain A");
AppDomain newDomainB = AppDomain.CreateDomain("new domain B"); FooA fooA = (FooA)newDomainA.CreateInstanceAndUnwrap(typeof(FooA).Assembly.FullName, typeof(FooA).FullName);
//FooB fooB = (FooB)newDomainB.CreateInstanceAndUnwrap(typeof(FooB).Assembly.FullName, typeof(FooB).FullName);
FooB fooB = new FooB();
Console.WriteLine(fooA.SayHello(fooB)); // 在客户端应用程序域中调用FooA对象的方法,并将FooB对象作为参数传递进去
AppDomain.Unload(newDomainA);
AppDomain.Unload(newDomainB);
Console.ReadLine(); } }

output:

Hello from new domain A. FooB says: Hello from Learn.exe
public class FooA : MarshalByRefObject
{
public string SayHello(FooB b) => $"Hello from {AppDomain.CurrentDomain.FriendlyName}. FooB says: {b.SayHello()}";
} public class FooB : MarshalByRefObject
{
public string SayHello() => $"Hello from {AppDomain.CurrentDomain.FriendlyName}";
}
class ProgramA
{
static void Main()
{
AppDomain newDomainA = AppDomain.CreateDomain("new domain A");
AppDomain newDomainB = AppDomain.CreateDomain("new domain B"); FooA fooA = (FooA)newDomainA.CreateInstanceAndUnwrap(typeof(FooA).Assembly.FullName, typeof(FooA).FullName);
FooB fooB = (FooB)newDomainB.CreateInstanceAndUnwrap(typeof(FooB).Assembly.FullName, typeof(FooB).FullName);
//FooB fooB = new FooB();
Console.WriteLine(fooA.SayHello(fooB)); // 在客户端应用程序域中调用FooA对象的方法,并将FooB对象作为参数传递进去
AppDomain.Unload(newDomainA);
AppDomain.Unload(newDomainB);
Console.ReadLine(); } }

output:

Hello from new domain A. FooB says: Hello from new domain B

C# 应用程序域的更多相关文章

  1. 【.net 深呼吸】跨应用程序域执行程序集

    应用程序域,你在网上可以查到它的定义,凡是概念性的东西,大伙儿只需要会搜索就行,内容看了就罢,不用去记忆,更不用去背,“名词解释”是大学考试里面最无聊最没水平的题型. 简单地说,应用程序域让你可以在一 ...

  2. .NET应用程序域

    在.NET平台下,可执行程序并没有直接承载在Windows进程中,而非托管程序是直接承载的..NET可执行程序承载在进程的一个逻辑分区中,称之为应用程序域(AppDomain).一个进程可以包含多个应 ...

  3. 读 《.Net 之美》解析.Net Remoting (应用程序域)-- Part.1

    读 <.Net 之美>解析.Net Remoting (应用程序域)-Part1 理解 .Net Remoting 前言: 看张子阳老师的文章,总是给自己很大的信心,这个专题基本上以张老师 ...

  4. 跨应用程序域(AppDomain)的单例(Singleton)实现

    转载自: 跨应用程序域(AppDomain)的单例(Singleton)实现 - CorePlex代码库 - CorePlex官方网站,Visual Studio插件,代码大全,代码仓库,代码整理,分 ...

  5. C#学习笔记----AppDomain应用程序域

    使用.Net建立的可执行程序*.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中.应用程序域是.Net引入的一个新概念,它比进程所占用的资源要少,可以被看做是一个轻量级 ...

  6. [转]C#综合揭秘——细说进程、应用程序域与上下文之间的关系

    引言 本文主要是介绍进程(Process).应用程序域(AppDomain)..NET上下文(Context)的概念与操作.虽然在一般的开发当中这三者并不常用,但熟悉三者的关系,深入了解其作用,对提高 ...

  7. [ActionScript 3.0] AS3.0 Loader加载子swf时是否需要指定新的应用程序域ApplicationDomain

    实际应用中, Loader加载子swf时是否需要指定新的应用程序域ApplicationDomain,需要择情况而定. 1.如果在本地将项目位置添加到flashplayer受信任位置(上一篇文章所述) ...

  8. [ActionScript 3.0] AS3 深入理解Flash的 应用程序域Application Domains

    简介 网上有很多flash,通常都不需要显示的使用应用程序域,因为默认的应用程序域就够用了.其实复杂的情况下需要用到应用程序域,比如说有两个不同的swf,一个是旧版本的,一个是新版的,这两个文件里的类 ...

  9. 应用程序域(Application Domain)

    应用程序域为隔离正在运行的应用程序提供了一种灵活而安全的方法. 应用程序域通常由运行时宿主创建和操作. 有时,您可能希望应用程序以编程方式与应用程序域交互,例如想在不停止应用程序运行的情况下卸载某个组 ...

  10. AppDomain 应用程序域

    应用程序域 一.什么是应用程序域? 应用程序域 (application domain) (AppDomain) 一种边界,它由公共语言运行库围绕同一应用程序范围内创建的对象建立(即,从应用程序入口点 ...

随机推荐

  1. Java 加密和解密

    在 Java 中,加密和解密通常通过 Java Cryptography Architecture (JCA) 和 Java Cryptography Extension (JCE) 实现.以下是常见 ...

  2. Deepin 设置开机执行某sh文件

    背景 deepin系统上部署了Geoserver,但是每次开机后都得手动过去起,麻烦,故想着找个办法解决下 过程 在/etc/systemd/system目录下新建一个 geoserver.servi ...

  3. 全程使用 AI 从 0 到 1 写了个小工具

    背景 好长时间没写技术方面的文章了,主要的原因是AI的发展实在太快太快,尤其是从去年ChatGPT的普及到今年DeepSeek的爆火,AI的世界可谓是三天一个小变化五天一个大版本,AI的能力每天都在以 ...

  4. go krotos proto编译引用外部包 was not found or had errors

    前言 kratos protos 生成 pb.go 文件时,会出现引用其他 proto 文件报错 was not found or had errors,因找不到此文件而无法编译. 解决 首先我们先了 ...

  5. Java List和Array之间的转换

    import java.util.Arrays; import java.util.List; class Test { //Object数组向List的转换 public static List&l ...

  6. Linux下使用sz/rz命令从服务器下载或上传文件

    简介 Linux中rz命令和sz命令都可用于文件传输,而rz命令主要用于文件的上传,sz命令用于从Linux服务器下载文件到本地. 安装 yum安装 yum -y install lrzsz 源码安装 ...

  7. 证件用蓝底、红底、白底照片RGB颜色值

    蓝色: R:67 G:142 B:219: 红色: R:255 G:0 B:0: 白色: R:255 G:255 B:255. * PS:仅供参考,如有特殊要求,请按照相应要求调整色值.

  8. Joker 智能开发平台:低代码开发的革新力量

    在软件开发领域,开发效率与灵活性始终是开发者们追求的核心目标.随着技术的迅猛发展,低代码开发平台逐渐成为行业焦点,而 Joker 智能开发平台凭借其卓越的性能和创新的功能,脱颖而出,为开发者们带来了前 ...

  9. Delphi CheckListBox 用法

    for i := CheckListBox1.Items.Count-1 downto 0 do //从后面往前面删 begin if CheckListBox1.Checked[i] then // ...

  10. Spring AOP 应用

    Spring AOP 应用 1. 介绍 AOP:面向切面编程,对面向对象编程的一种补充. AOP可以将一些公用的代码,自然的嵌入到指定方法的指定位置. 比如: 如上图,我们现在有四个方法,我们想在每个 ...