应用程序和 AppDomain.CurrentDomain 有什么区别

What's the difference between Application and AppDomain.CurrentDomain

我对 Application class 和 AppDomain class 的用法有点困惑。
例如 Application.StartupPath 等于 AppDomain.CurrentDomain.BaseDirectory

我通常使用Application class,最近发现AppDomain - 谁能给我解释一下AppDomain class和它的用法?

他们没有任何共同点,真的。

Application 是 class 特定于 Windows Forms,一种 .NET GUI 技术。 Application.StartupPath 由 Kernel32 函数 GetModuleFileName 处理。通过不传递指向模块的指针,主模块的路径是 returned - 即 exe 文件,基本上。

AppDomain 是域隔离的核心 .NET 概念。基本上,它允许您在单个本机进程中隔离(当然不完美)多个应用程序。大多数应用程序只有一个 AppDomain,但您可以根据需要创建任意多个。应用程序域的基本路径由 Fusion 处理,这是一种 .NET 程序集加载技术。一个非常典型的例子是在 IIS 中托管的 ASP.NET 个应用程序 - 每个应用程序都有自己的 AppDomain,但它们都托管在单个本机进程中 ("application pool")。每个逻辑应用程序都可以在不影响其他应用程序的情况下重新启动,并且它们之间没有(简单的)访问权限,但是进程撕裂异常(例如 WhosebugException)仍然会杀死整个池。

另一个有点相关的有趣 class 是 Environment。您可以使用 Environment.CommandLine 获取进程命令行(其中包括可执行文件的路径,包括可执行文件的名称)。这基本上是 CLR 和底层系统之间的通信接口——在这种情况下,它负责保存应用程序的参数(由 OS 传递给 Main 函数)并使以后随时可用。

Environment.CommandLine 解析起来有点笨拙(它是原始命令行,基本上 - 我假设它在 Windows 上的约定与在 Linux 上的约定不同),但这是您始终 获取可执行文件的唯一途径。同样,Application.StartupPath 是特定于 Winforms 的,您可以有多个 AppDomain - 并且 AppDomain 可能甚至 没有 一个合理的 BaseDirectory.

.NET 反射 API 也为您提供了一些方法。例如,Assembly.GetEntryAssembly() 将为您提供可执行程序集 - 然而,这仅适用于主要 AppDomain - 其他域将有自己的入口程序集(事实上,它们通常只是 return null :))。您可以通过 Assembly.CodeBase 属性 获取程序集的路径,但请注意,这可能并不总是您所期望的。您还可以使用 Assembly.Location,或获取任何程序集模块的 FullyQualifiedName(同样,大多数程序集只有一个模块;同样,ASP.NET 是主要示例之一当情况并非如此时)。