【问题标题】:Stop timer in onDisconnect() event在 onDisconnect() 事件中停止计时器
【发布时间】:2014-06-02 06:29:54
【问题描述】:

我正在使用 SignalR 从数据库中为每个连接的客户端获取实时更新。每个客户端都有唯一的数据,所以我不能只运行一个实时更新实例。我为每个客户创建一个新对象。问题是对象有 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?
  }

【问题讨论】:

  • 我注意到您只有一个 DataHub 构造函数,并且它需要一个 RealTimeData 对象作为参数。 Hub是如何被实例化的?你用 SignalR 的依赖解析器注册了吗?
  • 是的,我在启动时添加了依赖解析器
  • 你有解决方案吗?

标签: c# timer signalr


【解决方案1】:

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

您最好的选择可能是将您的计时器存储在与Context.ConnectionId 分离的静态ConcurrentDictionary&lt;string, Timer&gt; 中。

【讨论】:

  • 感谢您的回答。这就是我要去的方向。你的回答证实这是最好的路线。
  • 我编辑了我的答案以表明由于 Dictionary 是静态的,因此为了线程安全,它实际上应该是 ConcurrentDictionary
  • 使用 ConcurrentDictionary,我们如何停止计时器?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多