AppDomain
以前,每个应用程序都在自己的进程地址空间中运行,由于进程之间是无法直接调用的,这可以保证应用程序的相互隔离,可以防止安全漏洞、数据破坏和其他不可预测的行为,确保应用程序的健壮性。但是在windows中创建进程的开销很大(Win32的CreateProcess函数的速度很慢,而且windows系统需要大量内存来虚拟化一个进程的地址空间),并且如果要在进程间相互通信是十分麻烦的。
所以,如果将这些应用程序放在一个进程中,但是像进程那样是相互隔离的,互不影响,单独卸载,那么应该可以弥补进程的部分不足。在托管程序中,应用程序域(AppDomain)可以做到这些。
应用程序域提供了一个更安全、用途更广的处理单元,公共语言运行库可使用该单元提供应用程序之间的隔离。您可以在具有同等隔离级别(存在于单独的进程中)的单个进程中运行几个应用程序域,而不会造成进程间调用或进程间切换等方面的额外开销。在一个进程内运行多个应用程序的能力显著增强了服务器的可伸缩性。
AppDomain的主要目的就是隔离应用程序
- AppDomain之间不能直接访问。只能通过“按引用封送”和“按值封送”来调用
- 可以单独卸载。注意不能卸载单个程序集或类型,只能卸载整个域
- 可以单独实施配置
AppDomain FirstChance异常通知:当异常首次抛出时,CLR会调用已向抛出异常的那个AppDomain登记的任何FirstChanceException回调方法(然后才会去查找对应的catch块和进行后续操作),因此可以利用这个机制监视AppDomain中抛出的异常(无论该异常是否被“吞噬”)。为了登记一个回调方法,只需要为AppDomain的实例事件FirstChanceException添加一个委托(参考这里和这里),例如:
public static void Main() { AppDomain.CurrentDomain.FirstChanceException += (sender, arg) => { Console.WriteLine(arg.Exception.StackTrace); }; try { var a = 0; Console.WriteLine(5 / a); } catch { } Console.ReadLine(); }