應用程序域進一步認識

新知識點:跨域

  • 一個AppDomain中建立的對象不能由另外一個AppDomain的代碼進行訪問,必須進行特殊的聲明,使用特殊的跨域調用;
  • AppDomain 能夠單獨配置;
  • 每一個AppDomain都有本身的Loader堆,記錄自AppDomain建立以來,訪問過哪些類型,每一個類型對象都有一個方法表,指向JIT編譯的本地代碼;

運行示例:dom

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Runtime.Remoting;

namespace FactoryMode
{
    [Serializable]
    public class Program : MarshalByRefObject
    {
        //在調用此方法時,觀察"調用堆棧",發現一次"外部代碼"的切換,代表自進行了一次跨域操做
        public void NotMainMethod()
        {
            //AppDomain.CurrentDomain 能夠獲得一樣的結果
            var curCallingDomain = Thread.GetDomain(); 

            var curCallingDomainName = curCallingDomain.FriendlyName;
            Console.WriteLine("Cross-domain calling, curdomain name={0}.", curCallingDomainName);
        }

        static void Main(string[] args)
        {
            var curCallingDomain = Thread.GetDomain();

            var curCallingDomainName = curCallingDomain.FriendlyName;
            Console.WriteLine("Default AppDomain's friendly name={0}.", curCallingDomainName);

            string exeAssembly = Assembly.GetExecutingAssembly().CodeBase;
            Console.WriteLine("Main assembly={0}.", exeAssembly);

            AppDomain otherDomain = null;
            Console.WriteLine("{0}Demo #1", Environment.NewLine);

            otherDomain = AppDomain.CreateDomain("AD #2", null, null);
            //在"AD#2"應用程序域中建立 Programs 對象,並向默認應用程序域返回它的引用;
            var mbrt = (Program)otherDomain.CreateInstanceFromAndUnwrap(exeAssembly, "FactoryMode.Program");
            Console.WriteLine("Type={0}", mbrt.GetType());
            Console.WriteLine("Is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));

            //利用引用調用方法,方法中的打印顯示出此時線程正運行在"AD#2"應用程序域中
            mbrt.NotMainMethod();
           
            Console.Read();

        }
    }
}
  • 進行跨域封送,必須支持序列化;
  • 例子展現了跨域的引用傳遞,另外還有值傳遞;
  • AppDomain 的構造 AppDomainSetup 參數決定了是否使用單獨的配置;

  備註:性能

  • 獲取程序集的路徑名,是用 CodeBase 字段 - -;
  • 要得到主程序集引用的其餘程序集,能夠經過對統一路徑下dll的加載來完成,並不須要反射什麼的其餘手段;

卸載AppDomain:spa

  • 掛機進程中執行過託管代碼的全部線程;
  • 檢查正在該AppDomain上運行的線程,與會返還到該AppDomain上運行的線程;
  • 拋出 ThreadAbortException,執行全部 finally 塊中的內容進行資源清理;
  • 在公共堆中遍歷已卸載AppDomain中的對象,進行標記後進行垃圾回收;
  • 恢復剩餘全部線程的執行;

監視AppDomain:線程

  很是好用的功能,能夠用來作資源監控,性能監測;code

  • MonitoringSurvivedProcessMemorySize: 靜態屬性,當前 CLR 控制的全部 AppDomain 正在使用的字節數;
  • MonitoringTotalAllocatedMemorySize: 實例屬性,返回特定的 AppDomain 已分配的字節數;
  • MonitoringSurvivedMemorySize: 實例屬性,返回特定的 AppDomain 正在使用的字節數;
  • MonitoringTotalProcessorTime: 實例屬性,返還特定的 AppDomain 的CPU佔用率;
相關文章
相關標籤/搜索