C#多线程场景下是否需在成员函数内保护this不被回收?
问题分析与解答
使用场景代码
class TheClient { void funcClient() { // 用于执行长耗时操作的局部对象 ClassLast objServ1 = new ClassLast(); // 在独立线程中启动ClassLast的长耗时方法 Thread thCaller = new Thread( objServ1.FunctionThatLastALot ); thCaller.Start(); // 现在退出funcClient,局部对象objServ1将被销毁(!) } }
核心疑问
当funcClient执行完毕后,局部对象objServ1是否会立即被垃圾回收?因为函数退出后该对象已无外部引用。C#是否存在内部机制,可在其成员方法运行期间阻止对象被回收?若对象可能在运行时被回收,下述自引用方案是否可行?
class ClassLast { void FuncThatLastALot() { // 自引用以防止被销毁 ClassLast me = this; // … // 执行操作,无需担心被销毁 // … } }
解答
不会立即被垃圾回收
虽然funcClient执行完毕后,局部变量objServ1的引用会消失,但启动的线程正在执行objServ1的实例方法FunctionThatLastALot——在这个方法的执行过程中,线程的调用栈里会持有对this(也就是objServ1对象本身)的引用,GC会识别到这个引用,不会将对象标记为可回收。C#有内置机制阻止实例方法执行时对象被回收
CLR在处理实例方法调用时,会确保方法执行期间,this引用始终有效。只要方法还在运行(线程未退出该方法),对象就不会被GC回收,不需要额外做处理。自引用方案完全没必要
你写的ClassLast me = this;属于多余操作。因为方法执行时已经有this的引用存在于调用栈中,足够阻止GC回收对象。额外声明自引用不会带来任何好处,反而属于冗余代码。
内容的提问来源于stack exchange,提问作者iksess
相关产品推荐
相关产品推荐

