GC.这里需要KeepAlive,或者我可以依赖局部变量和参数来保持对象存活
本文关键字:参数 对象 局部变量 依赖 这里 KeepAlive 我可以 或者 GC | 更新日期: 2023-09-27 18:19:15
我有一堆方法,使用不安全的代码,直接从WPF的WriteableBitmap
和BackBuffer
中读取。
这是不完全清楚我是否应该使用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
的引用仍然在堆栈上,但是再次,它似乎使用了实现细节。当然,编译器可以自由地合并bmp1
和bmp2
,因为它们永远不会同时存在,即使编译器永远不会这样做,JITter仍然可以,并且可能会(例如,通过将它们都存储在同一个寄存器中,第一个,然后另一个)。
GC.KeepAlive
来保证正确性?这是特别令人费解的,因为,显然,FxCop认为GC。KeepAlive总是不好的
我应该依赖局部变量/参数作为对象的有效引用吗?
。你的分析是正确的;当托管代码不再使用本地内存时,抖动完全有权利告诉垃圾收集器本地内存的内容已经死亡。
我应该总是使用GC吗?KeepAlive保证正确性?
是的。这就是它的作用
如果你调用了WriteableBitmap。在获得回缓冲区之前锁定,那么WriteableBitmap应该被固定,并且底层内存不会被移动。至少这是我对WriteableBitmapAPI的解释。
我已经广泛使用WriteableBitmap,特别是codeplex上的开源WriteableBitmapEx库(披露,我曾经为这个库贡献过一次,但它不是我的项目)。这使用锁定/访问Backbuffer(重复)/解锁/无效的模式来绘制。即使后缓冲IntPtr存储在结构体中并在应用程序中传递,我也从未遇到过这种模式的问题。
致以最诚挚的问候