c# - MarshalByRefObject becoming "disconnected at server" even while sponsored -
i writing game supports mods, safety sandboxing mods separate appdomain game engine (so can restrict capabilities of mods separately engine). however, objects in scripting domain engine keeps reference keep getting garbage collected , exception this:
object '/30b08873_4929_48a5_989c_e8e5cebc601f/lhejbssq8d8qsgvuulhbkqbo_615.rem' has been disconnected or not exist @ server.
on server side creating objects (using appdomaintoolkit:
// take in "script reference" name of type in scripting domain public reference<t> dereference<t>(scriptreference reference) t : marshalbyrefobject { // create remote instance of type t instance = (t)remotefunc.invoke<scriptreference, object>(_plugincontext.domain, reference, r => { var t = type.gettype(r.typename, true, false); return activator.createinstance(t); }); //return reference keeps object alive until disposed return new reference<t>(instance, reference.typename, reference.name); }
the idea reference<t> sponsor object , long stays alive object in remote domain stay alive. problem lies, accessing objects through reference , yet still "disconnected @ server" exception. here implementation of reference<t>:
public sealed class reference<t> : idisposable t : marshalbyrefobject { private innersponsor _sponsor; public t remoteobject { { return _sponsor.remoteobject; } } public string typename { get; private set; } public string name { get; private set; } public reference(t obj, string typename = null, string name = null) { typename = typename; name = name; _sponsor = new innersponsor(obj); } ~reference() { if (_sponsor != null) _sponsor.dispose(); _sponsor = null; } public void dispose() { _sponsor.dispose(); gc.suppressfinalize(this); } /// <summary> /// inner sponsor actual sponsor (and kept alive remoting system). /// if references reference lost, dispose sponsor in destructor /// </summary> private sealed class innersponsor : marshalbyrefobject, isponsor, idisposable { private readonly ilease _lease; private bool _isdisposed; public readonly t remoteobject; private bool _isunregistered = false; public innersponsor(t obj) { remoteobject = obj; _lease = (ilease)obj.getlifetimeservice(); _lease.register(this, sponsortime()); } public timespan renewal(ilease lease) { if (lease == null) throw new argumentnullexception("lease"); if (_isdisposed) { if (!_isunregistered) { _lease.unregister(this); _isunregistered = true; } return timespan.zero; } return sponsortime(); } private static timespan sponsortime() { return timespan.frommilliseconds(/*some value fetched configuration*/); } public void dispose() { _isdisposed = true; } } }
what doing wrong cause objects die whilst there live reference<t> them?
use clientsponsor class built .net. stable , simplistic.
it's people turn when working across appdomains. implementation looks fine, simple sponsortime()
not returning correct value config.
Comments
Post a Comment