Reputation: 13
I have data and I want to present it to a user without him needing to refresh the page. I am using Asp .net core SignalR like this:
using System.Threading;
using Microsoft.AspNetCore.SignalR;
using WSEP212.DomainLayer;
namespace WebApplication.Publisher
{
public class ChartNotifications : Hub
{
// Create the instance of ChartDataUpdate
// Send Data every 1 seconds
readonly int _updateInterval = 1000;
//Timer Class
private Timer _timer;
private volatile bool _sendingChartData = false;
private readonly object _chartUpateLock = new object();
PieChart pieChart = new PieChart();
public ChartNotifications() {}
public void InitChartData()
{
//Show Chart initially when InitChartData called first time
pieChart.SetPieChartData();
sendChartData(pieChart);
//Call GetChartData to send Chart data every chosen interval
GetChartData();
}
public void GetChartData()
{
_timer = new Timer(ChartTimerCallBack, null, _updateInterval, _updateInterval);
}
private void ChartTimerCallBack(object state)
{
if (_sendingChartData)
{
return;
}
lock (_chartUpateLock)
{
if (!_sendingChartData)
{
_sendingChartData = true;
pieChart.SetPieChartData();
sendChartData(pieChart);
_sendingChartData = false;
}
}
}
public async void sendChartData(PieChart chart)
{
await Clients.All.SendAsync("updateChart", chart.GetPieChartData());
}
}
}
But I get an error -> System.ObjectDisposedException: Cannot access a disposed object. Object name: 'ChartNotifications'.
on the client side it looks like this:
chartConnection.start().then(() => {
console.log("chart connection started");
chartConnection.invoke('InitChartData');
});
Can you please tell me what I am doing wrong? or any other idea to use signalR to do this task? I new to this so please if you can elaborate on your answers.
Thank you in advance!!
Upvotes: 1
Views: 1425
Reputation: 7129
This is not the recommended way to do this. The documentation explicitly says 'Hubs are transient' and 'Don't store state in a property on the hub class. Every hub method call is executed on a new hub instance.' So what you are trying to do, cannot be achieved this way.
What I would suggest you to do instead (no code provided, just some thoughts on architecture):
IServiceProvider
to the service constructorIServiceScope
and request an instance of IHubContext<ChartNotifications>
(see documentation)Upvotes: 1