c# - SignalR objects are not being deleted from the heap even when the hub connection is disposed -
i have web application sends messages server front end (javascript) client using signalr. however, there end (.net) client creates proxy hub. end client processes messages , sends them hub, , hub sends these messages front end client.
here snippet of end client creates hub connection , proxy send messages hub:
hubconnection hubconnection = new hubconnection(serverurl); ihubproxy hubproxy = hubconnection.createhubproxy(hubname); task t = task.run(() => hubconnection.start(new longpollingtransport())); t.waitandunwrap(); if (hubproxy != null && hubconnection.state == connectionstate.connected) { await hubproxy.invoke("messageclients", messageargs); }
there more code, covers essential part.
the key part is, every time message created, code called. means there hubconnection
object created every message needs sent hub, , front end client. after making memory dump, realized lot of objects remain on heap , causing memory leak. figured it's because i'm not disposing hub connection, since 1 of main culprits microsoft.aspnet.signalr.transports.longpollingtransport
, on thousand objects on heap after playing around website hour (doing things create these signalr messages).
so thought disposing hubconnection
fix things:
using (hubconnection hubconnection = this.createhubconnection()) { if (hubconnection != null) { ihubproxy hubproxy = this.startconnection(hubconnection); if (hubproxy != null && hubconnection.state == connectionstate.connected) { await hubproxy.invoke("messageclients", messageargs); } } } private hubconnection createhubconnection() { // basic auth set hubconnection hubconnection = new hubconnection(this.serverurl); hubconnection.headers.add('authtoken', basicauth); return hubconnection; } private ihubproxy startconnection(hubconnection hubconnection) { ihubproxy hubproxy = hubconnection.createhubproxy(this.hubname); task t = task.run(() => hubconnection.start(new longpollingtransport()) t.waitandunwrap(); return hubproxy; }
but after running process , attaching windbg it, when -!dumpheap -stat -type microsoft.aspnet.signalr.transports
, again see microsoft.aspnet.signalr.transports.longpollingtransport
there similar high figures objects on heap + memory. shouldn't using statement cause hubconnection
disposed , therefore removed heap? should doing fix memory leak?
it turns out disposing hub connection does work. conflating 2 concepts: disposing unmanaged resources , deleting objects heap.
i thought when using statement hubconnection
object finishes (i.e., when dispose called on hubconnection
), windbg no longer show object in memory dump. since memory dump based on what's on heap, , since disposing object doesn't delete object heap (just allows released , deleted garbage collector), still showing in windbg.
i played around application more until garbage collector did work, , found objects deleted later.
i should note original question emphasized type microsoft.aspnet.signalr.transports.longpollingtransport
, , because not disposing longpollingtransport
object either (when hubconnection.start(new longpollingtransport())
. code looks following:
using (hubconnection hubconnection = this.createhubconnection()) { if (hubconnection != null) { using (longpollingtransport lptransport = newlongpollingtransport()) { ihubproxy hubproxy = this.startconnection(hubconnection, lptransport); if (hubproxy != null && hubconnection.state == connectionstate.connected) { await hubproxy.invoke("messageclients", messageargs); } } } } private hubconnection createhubconnection() { // basic auth set hubconnection hubconnection = new hubconnection(this.serverurl); hubconnection.headers.add('authtoken', basicauth); return hubconnection; } private ihubproxy startconnection(hubconnection hubconnection, httpbasedtransport transport) { ihubproxy hubproxy = hubconnection.createhubproxy(this.hubname); task t = task.run(() => hubconnection.start(transport)); t.waitandunwrap(); return hubproxy; }
Comments
Post a Comment