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

Kin*_*her 2 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);
                //}
              });
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)

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

OnDisconneted正在执行的那一刻,我可以看到计时器得到更新enabled=false。出来后又从OnDisconnected timer.enabled得到true了。

Kev*_*vin 5

在此处阅读 Hub 对象生命周期。重要的部分是这个

因为 Hub 类的实例是瞬态的,所以不能使用它们来维护从一个方法调用到下一个方法调用的状态。每次服务器收到来自客户端的方法调用时,Hub 类的一个新实例都会处理该消息。要通过多个连接和方法调用维护状态,请使用其他一些方法,例如数据库、Hub 类上的静态变量,或者不是从 Hub 派生的其他类。如果在内存中持久化数据,在Hub类上使用静态变量等方法,应用域回收时数据会丢失。

每次创建新的集线器时,您基本上都会创建一个新的计时器。因此,您遇到了多个定时器,所有定时器都调用 Timer_Elapsed1 方法。您可以尝试将 Timer 设为静态并跟踪连接数。这样您就可以在所有客户端断开连接时停止计时器。请注意,如果应用程序域回收,即使是静态变量也容易丢失(如上面的文档中所指出的)。