GC.这里需要KeepAlive,或者我可以依赖局部变量和参数来保持对象存活

本文关键字:参数 对象 局部变量 依赖 这里 KeepAlive 我可以 或者 GC | 更新日期: 2023-09-27 18:19:15

我有一堆方法,使用不安全的代码,直接从WPF的WriteableBitmapBackBuffer中读取。

这是不完全清楚我是否应该使用GC.KeepAlive每当我做这样的事情:

int MyMethod(WriteableBitmap bmp)
{
    return DoUnsafeWork(bmp.BackBuffer);
}

一方面,在MyMethod的堆栈上仍然有对bmp的引用。另一方面,它似乎依赖于实现细节——这可能编译成一个尾部调用,例如,在输入DoUnsafeWork时不引用bmp

同样,想象下面的假设代码:

int MyMethod()
{
    WriteableBitmap bmp1 = getABitmap();
    var ptr = bmp.BackBuffer;
    WriteableBitmap bmp2 = getABitmap();
    return DoUnsafeWork(ptr, bmp2);
}

理论上,在方法返回之前,对bmp1的引用仍然在堆栈上,但是再次,它似乎使用了实现细节。当然,编译器可以自由地合并bmp1bmp2,因为它们永远不会同时存在,即使编译器永远不会这样做,JITter仍然可以,并且可能会(例如,通过将它们都存储在同一个寄存器中,第一个,然后另一个)。

所以,一般来说:我应该依赖局部变量/参数作为对象的有效引用,还是应该始终使用GC.KeepAlive来保证正确性?

这是特别令人费解的,因为,显然,FxCop认为GC。KeepAlive总是不好的

GC.这里需要KeepAlive,或者我可以依赖局部变量和参数来保持对象存活

我应该依赖局部变量/参数作为对象的有效引用吗?

。你的分析是正确的;当托管代码不再使用本地内存时,抖动完全有权利告诉垃圾收集器本地内存的内容已经死亡。

我应该总是使用GC吗?KeepAlive保证正确性?

是的。这就是它的作用

如果你调用了WriteableBitmap。在获得回缓冲区之前锁定,那么WriteableBitmap应该被固定,并且底层内存不会被移动。至少这是我对WriteableBitmapAPI的解释。

我已经广泛使用WriteableBitmap,特别是codeplex上的开源WriteableBitmapEx库(披露,我曾经为这个库贡献过一次,但它不是我的项目)。这使用锁定/访问Backbuffer(重复)/解锁/无效的模式来绘制。即使后缓冲IntPtr存储在结构体中并在应用程序中传递,我也从未遇到过这种模式的问题。

致以最诚挚的问候