可以';t使用SignalR停止计时器

本文关键字:SignalR 计时器 使用 可以 | 更新日期: 2023-09-27 18:22:34

我有一个SignalR项目,我使用System.Timers.Timer类每秒向网页发送通知。

在我的网页中,我有一个文本输入和两个按钮,一个用于使用文本输入中的过滤器值开始接收更新,另一个用于停止计时器。

问题是,如果在文本输入中输入了一个值,然后我单击开始按钮,我就会开始接收更新,这很好,但当我在文本输入输入中输入新值并再次单击开始按钮时,我会开始接收新值和旧值的更新。

如果我点击停止按钮,计时器将不会停止。

我尝试了timer.Stop(), timer.Close(), timer.Dispose(), timer.Enabled = false,但都没有停止计时器。

我还尝试设置timer.AutoReset = false,然后在经过的事件结束时手动启动计时器(如果布尔变量设置为true),但布尔变量从未更改。

我的猜测是,每次点击启动按钮,它都会在不同的线程上启动,而主线程中没有发生任何变化。

这是集线器代码:

public class HubClass : Hub
{
    System.Timers.Timer stock = new System.Timers.Timer();
    int id = 1;
    SqlCommand dataRetriver = new SqlCommand();
    bool getNextFeed = true;
public void Start(string user)
    {
        USERID = user;
        id = 1;

        dataRetriver.Connection = con;

        dataRetriver.CommandText = "GetData";
        dataRetriver.CommandType = CommandType.StoredProcedure;
        dataRetriver.Connection = con;
        param.ParameterName = "userId";
        param.Value = USERID;
        param2.ParameterName = "@id";
        param2.Value = id;
        dataRetriver.Parameters.Clear();
        dataRetriver.Parameters.Add(param);
        dataRetriver.Parameters.Add(param2);

        stock.Elapsed -= new ElapsedEventHandler(stock_Elapsed);
        stock.Elapsed += new ElapsedEventHandler(stock_Elapsed);
        stock.Interval = 1000;
        stock.AutoReset = false;
        stock.Start();
    }

    public void Stop()
    {
        //stock.Stop();
        getNextFeed = false;
        //stock.Start();
    }
    void stock_Elapsed(object sender, ElapsedEventArgs e)
    {
        var context = GlobalHost.ConnectionManager.GetHubContext<HubClass>();
        if (con.State == ConnectionState.Closed)
            con.Open();

        dataRetriver.Parameters.Clear();
        param2.Value = id;
        dataRetriver.Parameters.Add(param);
        dataRetriver.Parameters.Add(param2);
        SqlDataReader reader = dataRetriver.ExecuteReader();
        DataTable allData = new DataTable();
        allData.Load(reader);
        string jsonString = JsonConvert.SerializeObject(allData);
        context.Clients.All.broadCastMessage(jsonString);

        id = id + 1;
        con.Close();
        if (getNextFeed)
        {
            stock.Start();
        }
    }
    }

这是我的javascript代码:

$(function () {

        var chat = $.connection.hubClass;
        chat.client.broadCastMessage = function (msg) {
            //update html table data
        };
        $.connection.hub.logging = true;
        $.connection.hub.start().done(function () {
            console.log($.connection.hub.transport.name);
        });

        $("#btn_filter").click(function () {
            chat.server.start($("#txt_id").val());
        });

        $("#btn_stop").click(function () {
            chat.server.stop();
        });
    });

可以';t使用SignalR停止计时器

中心API指南:

每次需要处理Hub操作时,SignalR都会创建Hub类的新实例,例如客户端连接、断开连接或对服务器进行方法调用时。

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

简言之,您正在为每个到达集线器的请求创建一个新的时间实例,因此无论您对它做什么都不会影响您对上一个请求中创建的实例所做的操作。每个会话或每个应用程序(取决于您的需求)必须使用一个实例,并相应地存储它。

脏或正常

使用System.Threading.Timer并使用事件Tick而不是Elapsed。现在你的计时器应该停止在库存。停止();

但你可以做一个肮脏的变通办法,比如股票。Interval=Int32.MaxValue;