代表不需要固定.如果托管对象无法被垃圾收集器移动,则会固定该对象.如果编组信息是正确的,那么编组层将确保传递指向不动的东西的指针.
但是,上面的注释中您建议局部变量可能使委托保持活动,这表明对变量生命周期的误解.我推荐你的规范,其中说明:
局部变量的实际生命周期取决于实现.例如,编译器可能静态地确定块中的局部变量仅用于该块的一小部分.使用此分析,编译器可以生成导致变量存储的生命周期比其包含块短的代码.由本地引用变量引用的存储被回收,而与该本地引用变量的生命周期无关
换句话说,如果你说:
void M()
{
Foo foo = GetAFoo();
UnmanagedLibrary.DoSomethingToFoo(foo);
}
Run Code Online (Sandbox Code Playgroud)
然后允许抖动说"你知道,我发现在调用非托管调用之后,没有托管代码再次使用foo;因此我可以在那时从另一个线程中积极地回收该对象的存储".这意味着非托管调用可以在突然在另一个线程上释放时对该对象起作用.
如果Foo有一个析构函数,这尤其令人讨厌.当对象被非托管库使用时,终结代码可能会在另一个线程上运行,而天堂只知道将导致什么样的灾难.
在这种情况下,您需要使用KeepAlive来保持托管对象的活动.不要依赖局部变量; 局部变量具体记录为不保证保持活力.
有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspx.
您不需要固定它,但只要复制正在进行,您就需要保持对它的引用。
非托管代码调用的 thunk 被固定,但您必须确保委托没有被垃圾收集 - 因此是引用。