我在哪里放置GC.KeepAlive? [英] Where do I put GC.KeepAlive?

查看:181
本文介绍了我在哪里放置GC.KeepAlive?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在非托管代码中注册一个回调,但是看起来GC一直在收集我的引用.因此,我添加了GC.KeepAlive(callback_pin);,但没有任何效果.我不确定应该将GC.KeepAlive放在哪里.

I need to register a callback in unmanaged code, but it looks like GC keeps collecting my reference. So I added GC.KeepAlive(callback_pin); but it has no effect. I'm not sure where should I put GC.KeepAlive.

这是我在非托管事件中注册自己的回调的代码,它是从线程中调用的. (Some_Callback和Some_Method是外部对象)

This is the code where I register my own callback to the unmanaged event, it is called from a thread. (Some_Callback and Some_Method are external objects)

var callback_pin = new Some_Callback(MyManagedCallback);
GC.KeepAlive(callback_pin);
Some_Method(callback_pin);
return true;

以下是我导入非托管代码的方式.随附的文档建议我使用上述代码来使回调保持活动状态,但是由于在我的情况下永远不会触发该回调,因此我认为这不是正确的方法.有什么启示吗?

And below is how I imported the unmanaged code. The documentation which came with it suggests that I use the above-mentioned code in order to keep the callback alive, but since the callback is never fired in my case I don't think it's the right way to do it. Any enlightenments?

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
public delegate void Some_Callback(Int32 line, [MarshalAs(UnmanagedType.LPWStr)] string msg);

[DllImport("SOME_DLL.dll", CharSet = CharSet.Unicode)]
public static extern Int32 Some_Method(MulticastDelegate funcPtr, Int32 mask);

推荐答案

在代表它们作为参数参与的本机函数的运行期间,代表会自动存活"(技术术语为"rooted").

Delegates are automatically "kept alive" (the technical term is "rooted") for the duration of native functions in which they participate as parameters.

如果要调用的本机函数仅存储指针,则只需要特殊的代码即可使它们保持活动状态,然后在以后某个时刻,另一个函数(或线程)使用存储的指针.可以想象到那时,该框架可以垃圾回收您的委托.

You only need special code to keep them alive if the native function you're calling is only storing the pointer, then at some later point another function (or thread) uses the stored pointer. The framework could conceivably garbage collect your delegate by then.

此外,您的问题有所不同,如果委托被垃圾回收,则在调用它时会遇到访问冲突.如果什么也没发生,那么您的本机函数就是不调用它-调试它!

Besides, your issue is different, if the delegate was garbage collected you'd be getting an access violation when calling it. If nothing is happening, your native function simply isn't calling it -- debug it!

这篇关于我在哪里放置GC.KeepAlive?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆