Dre*_*rew 3 c# memory-leaks signalr signalr-hub
我有两个有关 SignalR 集线器连接的相关问题,但在讨论它们之前,我将仅提供一些有关我正在做的事情的背景信息。
语境
我有一个使用 SignalR 将通知从服务器发送到前端(Javascript)客户端的应用程序。但是,还有一个后端 (.NET) 客户端可以创建中心的代理。后端客户端处理通知并将其发送到集线器,然后集线器将这些通知发送到前端客户端。
更具体地说,我有一个通知处理类,我们称之为NotificationProcessor.cs。每次创建新通知时,NotificationProcessor都会实例化一个实例。实例化后NotificationProcessor,将设置与集线器的代理连接。我有一个类,HubProxyService.cs它创建HubConnection对象并IHubProxy从中创建对象。其片段如下:
this.HubConnection = new HubConnection(serverUrl);
this.HubProxy = HubConnection.CreateHubProxy(hubName);
Task t = Task.Run(() => this.HubConnection.Start(new LongPollingTransport()));
t.WaitAndUnwrap();
Run Code Online (Sandbox Code Playgroud)
NotificationProcessor然后使用该IHubProxy对象调用集线器中的方法。
我发现HubConnection每次创建对象都会被实例化,并且在完成后NotificationProcessor不处理会导致内存泄漏。HubConnection
问题
(1)为了避免内存泄漏,我需要HubConnection以某种方式进行处置。我读到我可以做到
Task.Run(() => this.HubConnection.Stop())
Run Code Online (Sandbox Code Playgroud)
问题是我不知道什么时候可以调用它。由于使用代理调用 hub 方法是异步的,我可以在调用 hub 方法后立即调用它吗?或者,如果从集线器向前端客户端发送通知出现延迟,这是否会导致问题?
我想另一种选择是将 HubConnection 初始化包装在 using 语句中,如下所示
using (HubConnection connection = new HubConnection(serverUrl))
{
}
Run Code Online (Sandbox Code Playgroud)
我听说这也可能有问题,因为处理HubConnection可能需要一段时间。
有一个比另一个更好吗?后者似乎更惯用,而前者更明确并且可能效果更好。
(2) 为创建的HubConnection每个实例创建 是一个坏主意吗?NotificationProcessor有没有办法保持此连接(即使其静态或类似的东西)?我对对象生命周期和副作用的理解不稳定,特别是因为这个应用程序部署在云上,并且我不知道一个HubConnection实例多次使用意味着什么。它在线程之间共享吗?在节点之间(我使用的是 Redis 背板)?用户之间?如果每次需要发送数据时保持实例化连接的成本很高,那么保持连接打开是有意义的,但我只是不明白当它跨多个节点部署在云上时它是如何工作的。每次建立新的联系似乎更容易继续下去。
小智 5
这个问题很早以前就有人提出过,但是看到没有人回复,我想我应该插话一下。
鉴于您所描述的内容,我个人建议为每个处理器重用 HubConnection 的静态实例,并为每个处理器使用新的 HubProxy。只要确保在处置处理器时可以正确处置 IHubProxy 即可。
每个连接都将被视为 SignalR Hub 的单独客户端,因此如果您在同一进程内需要单独的通知或客户端,则需要单独的连接,但在您的情况下,让所有这些通知都源自同一客户端听起来很合适。
请务必检查HubConnection的线程安全性。
线程安全
此类型的任何公共静态(在 Visual Basic 中为共享)成员都是线程安全的。不保证任何实例成员都是线程安全的。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           5272 次  |  
        
|   最近记录:  |