Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak issue: how to dispose a SignalR hub connection and when to create a new connection

I have two related questions regarding SignalR hub connections, but before I get to them I'll just give some background info on what I'm doing.

Context

I have an application that sends notifications from the server to the front end (Javascript) client using SignalR. However, there is also a back end (.NET) client that creates a proxy to the hub. The back end client processes notifications and sends them to the hub, and the hub then sends these notifications to the front end client.

To be even more specific, I have a notification processing class, let's call it NotificationProcessor.cs. Each time a new notification is created, an instance of NotificationProcessor is instantiated. When NotificationProcessor is instantiated, the proxy connection to the hub is set up. I have a class, HubProxyService.cs, which creates the HubConnection object and the IHubProxy object from that. A snippet of it is as follows:

this.HubConnection = new HubConnection(serverUrl);
this.HubProxy = HubConnection.CreateHubProxy(hubName);
Task t = Task.Run(() => this.HubConnection.Start(new LongPollingTransport()));
t.WaitAndUnwrap();

NotificationProcessor then uses the IHubProxy object to invoke methods in the hub.

I have found that creating the HubConnection object each time NotificationProcessor is instantiated and not disposing the HubConnection when it's done causes a memory leak.

Questions

(1) To avoid the memory leak, I need to dispose HubConnection somehow. I read that I can do

Task.Run(() => this.HubConnection.Stop())

The problem with this is that I don't know at what point I can call this. Since the invoking the hub method with the proxy is asynchronous, can I just call it right after I invoke the hub method? Or will this cause issues in case there's a delay in sending the notification from the hub to the front end client?

I suppose another option would be to wrap the HubConnection initialization in a using statement, like so

using (HubConnection connection = new HubConnection(serverUrl))
{

}

I've heard that this can be problematic too because disposing HubConnection can take a while.

Is there one that's better than the other? The latter seems more idiomatic, whereas the former is more explicit and may work better.

(2) Is it a bad idea to create the HubConnection for every instance of NotificationProcessor that is created? Is there a way to persist this connection (i.e., make it static or something similar)? I have a shaky understanding of object lifetimes and the side effects, especially because this application is deployed on cloud and I don't know what it means for one HubConnection instance to be used more than once. Is it shared between threads? Between nodes (I'm using a Redis backplane)? Between users? It makes sense to keep the connection open if it's expensive to keep instantiating it every time data needs to be sent, but I just don't understand how it works when it's deployed on cloud across multiple nodes. It just seems easier to keep going with making a new connection each time.

like image 353
Drew Avatar asked Oct 23 '25 15:10

Drew


1 Answers

This question was posted a while ago but seeing no response, I thought I would chime in.

Given what you've described, I would personally recommend a static instance of the HubConnection be reused for each processor with a new HubProxy for each processor. Just be sure that the IHubProxy can be disposed properly when the processor is disposed.

Each connection will be treated as a separate client to the SignalR Hub so if you needed separate notifications or clients inside the same process, you would need separate connections but in your case, it sounds appropriate to have all of these notifications originate from the same client.

Word of Caution

Be sure to review the thread safety of the HubConnection.

Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

like image 117
Levi Rhoads Avatar answered Oct 25 '25 05:10

Levi Rhoads