我正在使用SignalR从数据库中为每个连接的客户端获取实时更新。每个clinet都有唯一的数据,因此我只能运行一个实时更新实例。我为每个客户创建一个新对象。问题是该对象具有System.Threading.Timer,它每秒运行一次回调以从数据库获取更新。即使在客户端断开连接后,计时器仍继续运行。我无法在断开连接事件中访问对象。我该如何阻止它?
public class DataHub : Hub
{
private readonly RealTimeData data;
public DataHub(RealTimeData rdata)
{
data = rdata;
}
public void Start(Int64 routerId)
{
data.StartTimer(routerId);
}
}
public class RealTimeData
{
private IHubConnectionContext Clients;
public Timer timer;
private readonly int updateInterval = 1000;
private readonly object updateRecievedDataLock = new object();
private bool updateReceivedData = false;
List<Items> allItems = new List<Items>();
public void StartTimer(Int64 routerId)
{
this.routerId = routerId;
timer = new Timer(GetDataForAllItems, null, updateInterval, updateInterval);
}
public void GetDataForAllItems(object state)
{
if (updateReceivedData)
{
return;
}
lock (updateRecievedDataLock)
{
if (!updateReceivedData)
{
updateReceivedData = true;
//get data from database
allItems = Mapper.Instance.GetDataForAllItems(routerId);
updateReceivedData = false;
//send it to the browser for update
BroadcastData(allItems);
}
}
}
}
public override Task OnDisconnected()
{
//before ondisconnect is called datahub construtor is called and a new instace of real time data is made. So I can't have access to previous object here. Where do I stop the timer?
}
答案 0 :(得分:2)
SignalR Hubs是短暂的。 SignalR每次调用包含Hub事件的Hub方法(例如OnDisconnected)时都会实例化一个新的Hub。由于您已将Hub添加到SignalR的依赖项解析程序,这意味着SignalR将为每次连接/断开/调用重新解析集线器。
您最好的选择可能是将您的计时器存放在ConcurrentDictionary<string, Timer>
的静态Context.ConnectionId
关键字中。