我从 C# 应用程序调用 CopyFileEx,并将匿名委托(delegate)传递到 LPPROGRESS_ROUTINE 参数,以便获得有关文件复制进度的通知。
我的问题是,是否需要固定匿名代表以及为什么(或为什么不需要)。
此外,如果出现以下情况,答案是否会发生变化:
- CopyFileEx 没有阻塞。
- 如果我传递了一个非匿名委托(delegate)。
谢谢!
最佳答案
代理不需要固定。如果垃圾收集器无法移动,则托管对象将被固定。如果编码信息正确,则编码层将确保传递指向固定对象的指针。
但是,上面您建议局部变量可能使委托(delegate)保持事件 的注释表明对变量生命周期的误解。我建议您引用规范,其中指出:
The actual lifetime of a local variable is implementation-dependent. For example, a compiler might statically determine that a local variable in a block is only used for a small portion of that block. Using this analysis, the compiler could generate code that results in the variable’s storage having a shorter lifetime than its containing block. The storage referred to by a local reference variable is reclaimed independently of the lifetime of that local reference variable
换句话说,如果你说:
void M()
{
Foo foo = GetAFoo();
UnmanagedLibrary.DoSomethingToFoo(foo);
}
然后允许抖动说“你知道,我看到在调用非托管调用后没有托管代码再次使用 foo;因此我可以积极地从另一个线程回收该对象的存储 那个时候”。这意味着当对象突然在另一个线程上被释放时,非托管调用可以在该对象上工作。
如果 Foo 有一个析构函数,这尤其令人讨厌。当非托管库正在使用对象时,终结代码可能会在另一个线程上运行,天知道会造成什么样的灾难。
在这种情况下,您需要使用 KeepAlive 来使托管对象保持事件状态。不要依赖局部变量;局部变量被特别记录为不保证保持事件状态。
参见 http://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspx了解更多详情。
关于c# - 我需要固定匿名代表吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5465060/