如何在signalR中的OnDisconnected事件处停止计时器

时间:2017-01-04 08:07:15

标签: c# asp.net timer signalr

我在客户端请求的PushNotificationData方法中建立了集线器连接时启动了计时器。

根据计时器间隔,它会从数据库中获取记录并推送到客户端。 但是当客户端断开连接时,必须停止此计时器而不是连续拉动。

所以我使用了OnDisconnected事件来停止计时器。但不幸的是计时器没有停止

这是我的代码:

public class NotifyHub : Hub
{
    private string ConnectionId;
    private int UserId;
    private int UserTypeId;

    Timer timer = new Timer();

    public override Task OnConnected()
    {
        ConnectionId = Context.ConnectionId;
        return base.OnConnected();
    }
    public override Task OnDisconnected(bool stopCalled)
    {
        timer.Stop();
        timer.Enabled = false;
        //logic code removed for brevity
        return base.OnDisconnected(stopCalled);
    }
    public void PushNotificationData(Int32 userId, Int16 userTypeId)
    {

        UserId = userId;
        UserTypeId = userTypeId;
        ConnectionId = Context.ConnectionId;

        timer.Elapsed += Timer_Elapsed1;
        timer.Interval = 6000;
        timer.Enabled = true;
        timer.Start();

    }

    private void Timer_Elapsed1(object sender, ElapsedEventArgs e)
    {
        var notificationParams = new PushNotificationRequest
        {
            FilterProperty = new Common.Filters.FilterProperty { Offset = 0, RecordLimit = 0, OrderBy = "datechecked desc" },
            Filters = new List<Common.Filters.FilterObject> { new Common.Filters.FilterObject { LogicOperator = 0, ConditionOperator = 0, Function = 0, FieldName = "", FieldValue = "", FieldType = 0 } }
        };
        using (INotificationManager iNotifity = new NotificationManager())
        {
            var taskTimer = Task.Run(async () =>
            {                        
                var NotificationResult = iNotifity.GetPushNotificationData(notificationParams, UserId, UserTypeId);
                //Sending the response data to all the clients based on ConnectionId through the client method NotificationToClient()
                Clients.Client(ConnectionId).NotificationToClient(NotificationResult);
                //Delaying by 6 seconds.
                await Task.Delay(1000);
                //}
              });
        }
    } 
}

当我调试它时,即使在enabled=true触发后它也会显示计时器OnDisconnected

OnDisconneted正在执行时,我可以看到计时器更新enabled=false。在它再次从OnDisconnected timer.enabled获得true之后。

1 个答案:

答案 0 :(得分:4)

了解Hub对象的生命周期here。重要的是这个

  

由于Hub类的实例是瞬态的,因此您无法使用它们来保持从一个方法调用到下一个方法调用的状态。每次服务器从客户端接收方法调用时,Hub类的新实例都会处理该消息。要通过多个连接和方法调用来维护状态,请使用其他方法,例如数据库,Hub类上的静态变量,或不从Hub派生的其他类。如果将数据保留在内存中,使用Hub类上的静态变量等方法,那么当应用程序域回收时,数据将会丢失。

每次创建新Hub时,您基本上都会创建一个新计时器。所以你使用多个定时器调用Timer_Elapsed1方法。您可以尝试使Timer静态并跟踪连接计数。这样,当所有客户端断开连接时,您可以停止计时器。请注意,即使静态变量很容易丢失,如果应用程序域回收(如上文中所述)。