簡體   English   中英

確定托管與非托管資源

[英]Determine managed vs unmanaged resources

有關托管與非托管資源的問題很多。 我理解這兩者的基本定義。 但是,我很難知道資源或對象何時被管理或不受管理。

當我想到非托管資源時,我傾向於考慮不直接屬於.NET的本機代碼,例如pinvoke或編組資源。 我通常認為資源意味着與使用硬件的東西接口,例如文件句柄或網絡連接也是不受管理的。

那些包裝本機非托管資源(如FileStream .NET對象呢?

FileStream必須使用非托管資源,但是當我實現IDisposable模式時,我應該將其視為托管或非托管資源嗎?

到目前為止,我一直在假設如果對象實現了IDisposable ,那么它就被管理了。 我怎么知道IntPtr應該作為非托管resoruce處理?

FileStream必須使用非托管資源,但是當我實現IDisposable模式時,我應該將其視為托管或非托管資源嗎?

FileStream是托管資源

托管資源是包含(並且必須管理)非托管資源的類。 通常,實際資源是幾層。

到目前為止,我一直在假設如果對象實現了IDisposable ,那么它就被管理了。

正確。

我怎么知道IntPtr應該作為非托管resoruce處理?

從您獲得其價值的API文檔。 但請注意,在實踐中,大多數程序員從不直接處理非托管資源。 當您需要時,使用SafeHandle類將非托管資源轉換為托管資源。

它非常簡單,您永遠不會意外地分配非托管資源。 你需要一個pinvoke調用來分配它,你知道它。 術語“對象”被重載,但是沒有非托管對象這樣的東西,.NET程序中的所有對象都被管理。 您可以使用另一種支持創建對象的語言(如C ++)編寫代碼。 但是你不能直接使用這樣的對象,需要C ++ / CLI包裝器。 這使它成為實現IDisposable的托管類。

如果您使用記錄不良的庫,那么在獲得IntPtr時請注意。 這是一個非常強烈的跡象,表明涉及非托管分配,指向非托管內存或操作系統句柄。 那么該庫也應該為您提供一種釋放它的方法,如果它沒有自動管理它。 如果您不確定如何正確處理它,請聯系圖書館的所有者。

微軟的工作是圍繞所有常見的操作系統資源提供托管包裝類。 像FileStream,Socket等。 這些類幾乎總是實現IDisposable。 當您在自己的類中存儲這樣的類對象時,您在代碼中唯一要做的就是自己實現IDisposable,這樣就可以在這些對象上調用Dispose()方法。 如果將它們用作方法中的局部變量,請使用using語句。

在這種情況下,將“資源”視為“某個對象已經代表其他人做了其他事情,直到另行通知,對其他人有害”是最有幫助的。 如果放棄它將導致垃圾收集器通知放棄對象,則該對象構成“受管資源”,並且該對象反過來指示代表其行事的任何東西停止這樣做。 “非托管資源”是未封裝在托管資源中的資源。

如果某個對象Foo托管內存分配一個句柄,它會要求內存管理器授予它對某些內存區域的獨占使用權,使其對其他可能不想使用它的代碼不可用,直到Foo通知內存為止。經理不再需要記憶,因此應該可以用於其他目的。 使句柄成為非托管資源的原因不在於它是通過API接收的,而是即使所有故意引用它都被放棄的事實,內存管理器將永遠繼續授予對象的獨占使用權。更長的需求(可能不再存在)。

雖然API句柄是最常見的非托管資源,但也有無數其他類型。 監視器鎖和事件之類的東西完全存在於.net的托管代碼世界中,但是仍然可以代表非托管資源,因為獲取鎖並在代碼等待時放棄它可能導致代碼永遠等待,並且因為短暫的生命從長期存在的對象訂閱事件並且在被放棄之前未能取消訂閱的對象可能導致該長期存在的對象無限期地繼續攜帶事件引用(如果只有一個訂閱者被放棄,則是一個小負擔,但是無限制的負擔如果創建並放棄了無限數量的訂戶)。

附錄垃圾收集器的一個基本假設是當對象X持有對象Y的引用時,這是因為X在Y中“感興趣”。然而,在某些情況下,引用可能被保持,因為X希望Y持有引用盡管Y不會“關心”這種或那種方式。 通知事件處理程序經常發生這種情況。 每當對象X發生某些事情時,對象Y可能希望得到通知。雖然X必須保持對Y的引用以便它可以執行這樣的通知,但X本身並不關心通知。 它只執行它們,因為假設一些有根的對象可能會關心Y接收它們。

在某些情況下,可以使用所謂的“弱事件模式”。 不幸的是,盡管.net中存在許多弱事件模式,但由於缺少適當的WeakDelegate類型,它們都存在怪癖和局限性。 此外,雖然弱事件是有幫助的,但它們不是靈丹妙葯。 例如,假設Y已經要求長期存在的對象X在事情發生時通知它,對Y的唯一現有引用是X用於此類通知的那個, Y對此類通知唯一做的就是增加屬性一些對象Z ,並設置該屬性在Z之外不修改任何內容。 在這種情況下,即使對象Z是宇宙中唯一“關心”對象YZ也不會對Y任何類型的引用,因此垃圾收集器無法綁定Y '與Z的生命相同。 如果XY有強烈的引用,那么即使沒有人對它感興趣,后者也會保持活力。 如果X只持有弱引用,那么即使Z對它感興趣, Y也可能被垃圾收集。 垃圾收集器沒有機制可以自動推斷ZY感興趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM