c# - 我需要固定匿名代表吗?

标签 c# winapi interop kernel32 pinning

我从 C# 应用程序调用 CopyFileEx,并将匿名委托(delegate)传递到 LPPROGRESS_ROUTINE 参数,以便获得有关文件复制进度的通知。

我的问题是,是否需要固定匿名代表以及为什么(或为什么不需要)。

此外,如果出现以下情况,答案是否会发生变化:

  1. CopyFileEx 没有阻塞。
  2. 如果我传递了一个非匿名委托(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/

相关文章:

c# - 如何在 Windows 8 应用程序中显示 "markdown"?

c++ - C++删除文件

c - GetConsoleScreenBufferInfo 获取单个控制台行的长度

c# - .NET 是否为 DispId 预定义了常量值?

c - 如何使用 Haskell 的 C 库?

未读取 C# MVC url 参数

c# - 实现键盘快捷键

c# - 如何处理失败的 DllImport?

c# - Microsoft 推送通知服务和 Windows Phone 7/8

c++ - WIN32内存问题(debug/release的区别)