1

I want to keep reference of managed ObjB in ObjA, and ensure ObjB instance survives until ObjA finalized. I need to call some ObjB methods in ObjA.~ObjA and only then let ObjB to die. There is only on reference to ObjB(in ObjA obviously). For now I found a way to keep ObjB alive, I store it in static List<ObjB>, and remove it from that list on ObjA.~ObjA.

So the question is - is there some fancy way to exclude object from GC and later enable it from finalizer of another object?

crashtua
  • 472
  • 2
  • 14
  • 3
    So long as A has a reference to B and A is alive, B is alive. Unless you purposefully dispose of B, I can't think of a reason why B would be disposed until A has been disposed. Is this a problem you are actually having or a problem you think you might have and are trying to solve without actually having seen it be a problem? – gilliduck Apr 23 '23 at 13:17
  • 1
    @gilliduck Not quite true: when it comes to finalizers all bets are off and a managed object might have been disposed. See also https://stackoverflow.com/a/2327618/14868997 – Charlieface Apr 23 '23 at 13:29
  • Why do you have a finalizer anyway, what does it need to do that you think it needs one? – Charlieface Apr 23 '23 at 13:29
  • Story behind this request - third party managed wrapper library around unmanaged code. Sometimes ObjB GCed too early and then resurrected by native code, some internals of ObjB not resurrected but native code still tries to call already finalized managed code. Only way to keep happy that wrappers - keep ObjB reference alive. – crashtua Apr 23 '23 at 13:33
  • _"Sometimes ObjB GCed too early and then resurrected by native code"_ When it was GCed and when the native code rescurrected it? You are able to know the time and prevent the native code to do so after the object is GCed. – shingo Apr 23 '23 at 14:11

1 Answers1

2

Ultimately, once GC is in play: it is too late - everything is non-deterministic. A will keep B alive, but only if A is also being kept alive. Finalizers shouldn't really talk to any other objects.

There are two solutions to your scenario:

  1. Make sure that A stays reachable via some object root, so neither A nor B becomes collectable, or
  2. Use a GCHandle, noting that it is your responsibility to allocate and release the handle appropriately

The first option is usually easier and more appropriate.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • GCHandle is something I was looking for. But still will stick to option 1 but keep B in object root. – crashtua Apr 28 '23 at 07:19