In my game, people connect to my server. The server creates a GamePeer
per connection. GamePeer
creates one HelpersContainer
that contains all helpers. Any helpers must see any other helpers.
//1 network peer = 1 GamePeer object
class GamePeer
{
HelpersContainer helpersContainer = new HelpersContainer(dbWorker)
...
}
//Contain all helpers
class HelpersContainer
{
public IDBWorker DBWorker {get; private set;}
public UserHelper UserHelper {get; private set;}
public BuildingHelper BuildingHelper {get; private set;}
public StarsHelper StarsHelper {get; private set;}
//WeakReference for GC can collect objects
private WeakReference ThisWeakReference = new WeakReference(this);
public HelpersContainer(IDBWorker dbWorker)
{
this.DBWorker = dbWorker;
this.UserHelper = new UserHelper(ThisWeakReference.Target);
this.BuildingHelper = new BuildingHelper(ThisWeakReference.Target);
this.StarsHelper = new StarsHelper(ThisWeakReference.Target);
}
}
class UserHelper
{
private HelpersContainer HContainer;
public UserHelper(HelpersContainer hContainer)
{
this.HContainer = hContainer;
}
public GetUsersInGalaxy(int galaxyId, IEnumerable<User> allUsers = null, IEnumerable<Star> allStars = null)
{
if(allUsers == null)
allUsers = HContainer.DBWorker.GetAll<User>();
if(allStars == null)
allStars = HContainer.StarsHelper.GetStarsForPeoples();
var starsInGalaxy = allStars.Where(x => x.galaxyId == galaxyId);
return allUsers.Where(x => starsInGalaxy.Any(y => y.Id == x.starId));
}
}
-
\$\begingroup\$ And helpers can't be static becose i don't want put DBWorker in all methods as argument. \$\endgroup\$Glebka– Glebka2015年03月30日 16:34:23 +00:00Commented Mar 30, 2015 at 16:34
1 Answer 1
You haven't asked any specific questions, so here's a generic critique.
private WeakReference ThisWeakReference = new WeakReference(this);
I don't think this is going to solve whatever problem you want it to, at least the way you are using it here. Circular references aren't a problem with garbage collection, the way they can be with reference counting management techniques. The GC will see that the whole group is no longer reachable from a GC root and clean them all up. Furthermore, this isn't the correct way to use a WeakReference
- your objects all end up with regular references in the end. What you would do is entirely replace
private HelpersContainer HContainer;
with
private WeakReference HContainer;
Then each time you want to use it you would check if Target
is null (meaning it has been collected). You would have to figure out what to do if it has been cleaned up and your object has one of its functions invoked that require it. But this is moot because as far as I can tell the whole weak reference thing is unnecessary.
I'd say you should pass in to each Helper
any of the other Helper
s that it needs, in its constructor. If your dependencies are such that this isn't possible, I think it suggests that your classes are too interdependent.
Also, Helper
is a very generic name. Is there another word that more accurately describes what the classes do? Do they all have to have the same word?
-
\$\begingroup\$ How can i solve problem of memory leak? If child object referenced to parent, is GC collect parent and children after gamePeer finish the job? \$\endgroup\$Glebka– Glebka2015年03月30日 19:21:49 +00:00Commented Mar 30, 2015 at 19:21
-
\$\begingroup\$ @GLeBaTi: I've updated the answer \$\endgroup\$Pierre Menard– Pierre Menard2015年03月31日 00:26:05 +00:00Commented Mar 31, 2015 at 0:26