2017-09-12 46 views
1

我有從服務器向使用SignalR前端(JavaScript)的客戶端發送消息的web應用程序。但是,還有一個後端(.NET)客戶端可以爲集線器創建代理。後端客戶端處理消息並將其發送到集線器,然後集線器將這些消息發送到前端客戶端。SignalR對象不被從堆中刪除即使當輪轂連接設置

下面是創建的輪轂連接和代理將消息發送到集線器的後端客戶端的一個片段:

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); 
} 

顯然有更多的代碼,但覆蓋重要組成部分。

的關鍵部分是,每次創建一個消息的時候,這個代碼將被調用。這意味着爲每個需要發送到集線器,然後發送到前端客戶端的消息創建一個HubConnection對象。 進行內存轉儲後,我意識到很多對象留在堆上並導致內存泄漏。我想這是因爲我不處置的輪轂連接,由於主要元兇之一是Microsoft.AspNet.SignalR.Transports.LongPollingTransport,對堆過千對象與網站玩耍了大約一個小時(做的事情,會造成這些SignalR消息)之後。

所以我想處置HubConnection會解決的事情:

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() 
{ 
    // do some basic auth set up 
    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; 
} 

但在運行過程中和安裝的WinDbg它,當我做-!dumpheap -stat -type Microsoft.AspNet.SignalR.Transports,我再次看到Microsoft.AspNet.SignalR.Transports.LongPollingTransport那裏與類似的高數據上的對象後,堆+內存。不應該使用陳述導致HubConnection被丟棄並因此從堆中移除?我應該如何解決這個內存泄漏問題?

回答

0

事實證明,配置集線器連接確實工作。我正在混淆兩個概念:處理非託管資源並從堆中刪除對象。

我認爲當HubConnection對象的使用語句完成時(即在HubConnection上調用dispose時),WinDbg將不再在內存轉儲中顯示該對象。但由於內存轉儲是基於什麼是在堆上,由於處置的對象不從堆中刪除對象(只允許它被釋放,並通過垃圾收集器刪除),它仍然在WinDbg中顯示。

我更多,直到垃圾收集器起了作用的應用發揮各地,發現的對象,後來被刪除。

我也應該注意到,我原來的問題強調類型Microsoft.AspNet.SignalR.Transports.LongPollingTransport,那是因爲我沒有處置的LongPollingTransport對象是(當我做hubConnection.Start(new LongPollingTransport())所以我的代碼現在看起來像如下:

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() 
{ 
    // do some basic auth set up 
    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; 
} 
相關問題