C# onDisconnect()事件中的停止计时器

C# onDisconnect()事件中的停止计时器,c#,timer,signalr,C#,Timer,Signalr,我使用SignalR从数据库中获取每个连接客户端的实时更新。每个clinet都有唯一的数据,所以我不能只运行一个实时更新实例。我为每个客户端创建一个新对象。问题在于,该对象具有System.Threading.Timer,它每秒运行一次回调以从数据库获取更新。即使在客户端断开连接后,计时器也会继续运行。在断开连接事件中,我无权访问对象。我该怎么阻止它 public class DataHub : Hub { private readonly RealTimeData data; public

我使用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?
  }
公共类数据集线器:集线器
{
私有只读实时数据;
公共数据中心(RealTimeData rdata)
{
数据=rdata;
}
公共无效启动(Int64路由ID)
{
数据。StartTimer(routerId);
}
}
公共类实时数据
{   
私人IHubConnectionContext客户端;
公共定时器;
私有只读int updateInterval=1000;
私有只读对象updateRecievedDataLock=新对象();
private bool updateReceivedData=false;
列表所有项=新列表();
公共无效起始计时器(Int64路由ID)
{
this.routerId=routerId;
计时器=新计时器(GetDataForAllItems,null,updateInterval,updateInterval);
}
public void GetDataForAllItems(对象状态)
{
if(updateReceivedData)
{
返回;
}
锁(updateRecievedDataLock)
{
如果(!updateReceivedData)
{
updateReceivedData=true;
//从数据库获取数据
allItems=Mapper.Instance.GetDataForAllItems(routerId);
updateReceivedData=false;
//将其发送到浏览器进行更新
广播数据(allItems);
}
}
}
}
公共覆盖任务OnDisconnected()
{
//在ondisconnect被称为datahub Constructor之前,调用datahub Constructor并创建一个新的实时数据安装。因此,我无法访问以前的对象。我在哪里停止计时器?
}

信号机集线器是短暂的。SignalR每次调用包含集线器事件(例如OnDisconnected)的集线器方法时,都会实例化一个新的集线器。由于您已将集线器添加到信号器的依赖项解析程序中,这意味着信号器将为每次连接/断开连接/调用重新解析集线器


您最好将计时器存储在一个静态的
ConcurrentDictionary
中,该字典由
上下文设置。ConnectionId

我注意到您只有一个
DataHub
构造函数,它将
RealTimeData
对象作为参数。如何实例化中心?您在SignalR的依赖项解析程序中注册了吗?是的,我在Startup中添加了依赖项解析程序。您得到了解决方案吗?谢谢您的回答。这就是我要去的方向。您的回答证实了这是最佳路径。我编辑了我的回答,以表明由于字典是静态的,因此为了线程安全起见,它实际上应该是一个
ConcurrentDictionary
。使用ConcurrentDictionary,我们如何停止计时器?