I am looking for a way to do this in C#:
- an Asker object will ask a Giver object for Resource objects.
- when asked, Giver will search it’s Dictionary for existing matching Resource. If found, it will return the reference of the Resource; otherwise, it will create a the new Resource from database data, save that reference in Dictionary, and finally return the reference.
- the Asker may ask for the same Resource more than once, in which case Giver will return the same Resource from the Dictionary the same number of times.
-
the Asker may at any time have no use for a given Resource, in which case, it does nothing further to the Resource.
-
Problem: How can Giver detect for any Resource that it is no longer in use and remove it from the Dictionary? Preferably, Giver should do this without Asker’s help.
Is this possible? I can’t seem to solve this.
EDIT:
Thanks everyone for the great replies. Especially the WeakReferences. I didn’t know they were there. But I have 2 main objectives which I could have specified clearer.
- Giver should not rely on Asker to get notified.
- While a given Resource is in use, all of the references must be pointing to the same Resource so that modification to the Resource is reflected in all places where the same Resource is used.
EDIT:
[Removed incorrect code block]
To start, what you’re talking about is the basic idea behind the
IDisposableinterface: a deterministic way for resources to be released. While its main usage is when interacting with unmanaged resources that require explicit release (or interacting with objects that do that), its usage is not restricted to that.Unfortunately, it fails your last requirement: since it’s deterministic, it has to be called by somebody. This somebody would have to be the Asker.
The only solution that I can come up with would be using the
WeakReferenceclass in yourGiverobject. This allows you to maintain a reference to an instance that doesn’t prevent it from being garbage collected (after it’s collected, your reference becomesnull).Unfortunately, this isn’t deterministic. Your reference will become
null(andIsAlivewill befalse) after the object is actually collected, which is not guaranteed to happen at any particular time (or at all during the lifetime of your application).With those caveats in mind, you could something like this: