假設您有一個.net對象bufferObject
,它在內部使用某種非相當大小的非託管內存緩衝區。它的實現方式是在處置(或最終)時釋放分配的內存。如何使用C#將對象生命週期與另一個對象生存期綁定在一起#
然後,您創建一個不同的對象reusingBufferObject
併爲其提供指向內部緩衝區的bufferObject
的指針。所以這兩個對象本身並不知道彼此的存在。
bufferObject
如果超出範圍,並且設置/完成,內部緩衝器將被釋放並reusingBufferObject
將訪問無效的內存。
當然,通過改變兩個對象的基礎分類的設計並且讓reusingBufferObject
參考bufferObject
可以避免整個問題。但是讓我們假設這兩個對象都是第三方類的實例,並且它們的設計不能改變。
一個例子就是使用一些圖像處理庫。內部圖像對象必須轉換爲Bitmap
對象才能在屏幕上顯示它,但出於性能原因,圖像對象內部緩衝區必須由Bitmap
對象重用,而不是僅複製到該對象。
是否有可能只reusingBufferObject
後的bufferObject
壽命綁的reusingBufferObject
壽命,所以它得到符合垃圾收集呢,不用手動保持一生的軌跡?
編輯:
這裏一個簡單的例子來說明這個問題:
namespace Example
{
// Some third party class with no control over its design.
// The Data property is the pointer to an unmanaged memory
// buffer.
public class ThirdPartyImage : IDisposable
{
public int Width { get; }
public int Height { get; }
public int Stride { get; }
public PixelFormat Format { get; }
public IntPtr Data { get; }
public ThirdPartyImage(string filename);
public Dispose();
}
public static class MyOwnExtensions
{
// Some method to reuse the internal memory buffer.
public static Bitmap ToBitmap(this ThirdPartyImage image)
{
return new Bitmap(image.Width, image.Height, image.Stride, image.Format,
image.Data);
}
}
class Program
{
static void Main(string[] args)
{
Bitmap bitmap = Foo();
// ThirdPartyImage is not referenced anymore and the internal buffer (Data)
// will be freed when garbage collected.
Bar(bitmap);
}
private static Bitmap Foo()
{
ThirdPartyImage image = ThirdPartyImage("foo.bmp");
Bitmap bitmap = image.ToBitmap();
return bitmap;
}
private static void Bar(Bitmap bitmap)
{
// Do some Bitmap related work here.
// The buffer could already be freed though.
}
}
}
編輯:
我所尋找的是像一個垃圾收集方法,即可以讓你將一個對象的生命期限與另一個對象相連
或者某種當正在收集或獲得符合回收,這樣我就可以建立包括持有的強引用bufferObject
和WeakReference
到reusingBufferObject
輔助對象一些自動化的機制reusingBufferObject
/Bitmap
通知。
手動跟蹤兩個實際上不再需要的對象(除了內部使用的緩衝區),例如引入一個包裝類,對我來說似乎過於複雜。
它取決於'bufferObject'派生自哪個類。另外,你能否提供有關一般涉及的類型的更多細節? 'bufferObject'和'reusingBufferObject'類型的元數據視圖將非常有用。 –
沒有更多細節,不可能回答這個問題。各種對象如何分配和銷燬的確切語義決定了這是否可以完成。 – xxbbcc
即使在'reusingBufferObject'之前沒有收集'bufferObject',你打算如何防止'bufferObject.Dispose()'調用? –