免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
關(guān)于appdomain, assembly, 進程,線程的概念體會
AppDomain是CLR的運行單元,它可以加載Assembly、創(chuàng)建對象以及執(zhí)行程序。
AppDomain是CLR實現(xiàn)代碼隔離的基本機制。
每一個AppDomain可以單獨運行、停止;每個AppDomain有自己默認的異常處理;
一個AppDomain的運行失敗不會影響到其他的AppDomain。
CLR在被CLR Host(windows shell or InternetExplorer or SQL Server)加載后,要創(chuàng)建一個默認的AppDomain,程序的入口點
(Main方法)就是在這個默認的AppDomain中執(zhí)行。
1.AppDomain vs 進程
AppDomain被創(chuàng)建在進程中,一個進程內(nèi)可以有多個AppDomain。一個AppDomain只能屬于一個進程。
2.AppDomain vs 線程
其實兩者本來沒什么好對比的。AppDomain是個靜態(tài)概念,只是限定了對象的邊界;線程是個動態(tài)概念,它可以運行在不同的
AppDomain。
一個AppDomain內(nèi)可以創(chuàng)建多個線程,但是不能限定這些線程只能在本AppDomain內(nèi)執(zhí)行代碼。
CLR中的System.Threading.Thread對象其實是個soft thread,它并不能被操作系統(tǒng)識別;操作系統(tǒng)能識別的是hard thread。
一個soft thread只屬于一個AppDomain,穿越AppDomain的是hard thread。當(dāng)hard thread訪問到某個AppDomain時,一個
AppDomain就會為之產(chǎn)生一個soft thread。
hard thread有thread local storage(TLS),這個存儲區(qū)被CLR用來存儲這個hard thread當(dāng)前對應(yīng)的AppDomain引用以及soft
thread引用。當(dāng)一個hard thread穿越到另外一個AppDomain時,TLS中的這些引用也會改變。
當(dāng)然這個說法很可能是和CLR的實現(xiàn)相關(guān)的。
3.AppDomain vs Assembly
Assembly是.Net程序的基本部署單元,它可以為CLR提供用于識別類型的元數(shù)據(jù)等等。Assembly不能單獨執(zhí)行,它必須被加載到
AppDomain中,然后由AppDomain創(chuàng)建程序集中的對象。
一個Assembly可以被多個AppDomain加載,一個AppDomain可以加載多個Assembly。
每個AppDomain引用到某個類型的時候需要把相應(yīng)的assembly在各自的AppDomain中初始化。因此,每個AppDomain會單獨保持一
個類的靜態(tài)變量。
4.AppDomain vs 對象
任何對象只能屬于一個AppDomain。AppDomain用來隔離對象,不同AppDomain之間的對象必須通過Proxy(reference type)或者
Clone(value type)通信。
引用類型需要繼承System.MarshalByRefObject才能被Marshal/UnMarshal(Proxy)。
值類型需要設(shè)置Serializable屬性才能被Marshal/UnMarshal(Clone)。
5.AppDomain vs Assembly Code
AppDomain和程序集的源代碼是什么關(guān)系呢?每個程序集的代碼會分別裝載到各個AppDomain中?
首先我們要把程序集分3類
1.mscorlib,這是每個.net程序都要引用到的程序集。
2.GAC,這個是強命名的公用程序集,可以被所有的.net程序引用。
3.Assembly not in GAC,這是普通的assembly,可以不是強命名,不放到GAC中。
啟動CLR,進入entry point時可以設(shè)置LoaderOptimization屬性:
[LoaderOptimization(LoaderOptimization.MultiDomain]
static void Main()
{...}
LoaderOptimization屬性可以設(shè)置三個不同的枚舉值,來設(shè)置針對前面說的三種程序集的代碼存放以及訪問方式。
LoaderOptimization Enumeration/Attribute
ValueExpected Domains in ProcessEach Domain Expected to Run ...Code for MSCORLIBCode for Assemblies in GACCode for Assemblies not in GAC
SingleDomainOneN/APer-processPer-domainPer-domain
MultiDomainManySame ProgramPer-processPer-processPer-process
MultiDomainHostManyDifferent ProgramsPer-processPer-processPer-domain

1.SingleDomain,由于只啟動一個AppDomain,那么code就被直接裝載到了AppDomain中,訪問靜態(tài)變量更快捷。
2.MultiDomain,所有的Assembly代碼是進程級別的,因此所有的AppDomain只訪問一份代碼。這大大減少了程序占用的內(nèi)存,但
是由于程序集的靜態(tài)變量仍然在各個AppDomain中,因此代碼訪問靜態(tài)變量需要先得到AppDomain的引用再進行轉(zhuǎn)換,速度會受到
影響。
3.MultiDomainHost,只有GAC代碼是共享的,非GAC的Assembly依然會加載到被使用的AppDomain中,這樣提高了靜態(tài)變量的訪問
速度,當(dāng)然也增加了程序占用的內(nèi)存。
不管是哪種方式,mscorlib始終是process級別的,即只有一份mscorlib代碼在內(nèi)存中。

C#中動態(tài)加載和卸載DLL

在C++中加載和卸載DLL是一件很容易的事,LoadLibrary和FreeLibrary讓你能夠輕易的在程序中加載DLL,然后在任何地方 卸載。在C#中我們也能使用Assembly.LoadFile實現(xiàn)動態(tài)加載DLL,但是當(dāng)你試圖卸載時,你會很驚訝的發(fā)現(xiàn)Assembly沒有提供任何 卸載的方法。這是由于托管代碼的自動垃圾回收機制會做這件事情,所以C#不提供釋放資源的函數(shù),一切由垃圾回收來做。

這引發(fā)了一個問題,用Assembly加載的DLL可能只在程序結(jié)束的時候才會被釋放,這也意味著在程序運行期間無法更新被加載的DLL。而這個功能在某 些程序設(shè)計時是非常必要的,考慮你正在用反射機制寫一個查看DLL中所有函數(shù)詳細信息的程序,程序提供一個菜單讓用戶可以選擇DLL文件,這時就需要讓程 序能夠卸載DLL,否則一旦用戶重新得到新版本DLL時,必須要重新啟動程序,重新選擇加載DLL文件,這樣的設(shè)計是用戶無法忍受的。

C#也提供了實現(xiàn)動態(tài)卸載DLL的方法,通過AppDomain來實現(xiàn)。AppDomain是一個獨立執(zhí)行應(yīng)用程序的環(huán)境,當(dāng)AppDomain被卸載的 時候,在該環(huán)境中的所有資源也將被回收。關(guān)于AppDomain的詳細資料參考MSDN。下面是使用AppDomain實現(xiàn)動態(tài)卸載DLL的代碼,

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Reflection;
namespace UnloadDll
{
class Program
{
static void Main(string[] args)
{
string callingDomainName = AppDomain.CurrentDomain.FriendlyName;//Thread.GetDomain().FriendlyName;
Console.WriteLine(callingDomainName);
AppDomain ad = AppDomain.CreateDomain("DLL Unload test");
ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap(@"UnloadDll.exe", "UnloadDll.ProxyObject");
obj.LoadAssembly();
obj.Invoke("TestDll.Class1", "Test", "It's a test");
AppDomain.Unload(ad);
obj = null;
Console.ReadLine();
}
}
class ProxyObject : MarshalByRefObject
{
Assembly assembly = null;
public void LoadAssembly()
{
assembly = Assembly.LoadFile(@"TestDLL.dll");
}
public bool Invoke(string fullClassName, string methodName, params Object[] args)
{
if(assembly == null)
return false;
Type tp = assembly.GetType(fullClassName);
if (tp == null)
return false;
MethodInfo method = tp.GetMethod(methodName);
if (method == null)
return false;
Object obj = Activator.CreateInstance(tp);
method.Invoke(obj, args);
return true;
}
}
}

注意:

1. 要想讓一個對象能夠穿過AppDomain邊界,必須要繼承MarshalByRefObject類,否則無法被其他AppDomain使用。

2. 每個線程都有一個默認的AppDomain,可以通過Thread.GetDomain()來得到

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Net托管世界的應(yīng)用程序域和線程
重溫CLR(十六) CLR寄宿和AppDomain
[CLR via C#]25. 線程基礎(chǔ)
C#中動態(tài)加載和卸載DLL
進程、應(yīng)用程序域、程序集、對象上下文
淺析.Net下的AppDomain編程
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服