** SignalR **多次触发SQLDependency

时间:2019-05-10 08:31:44

标签: c# asp.net signalr signalr-hub sqldependency

我有一个带有VS2013和.Net Framework 4.5.1的 ASP.Net MVC 监视应用程序,该应用程序应在数据库中有任何更改时自动刷新实时图表。当我打开浏览器的单个实例时,一切工作正常,但是当我在同一台计算机或另一台计算机上打开另一个选项卡或浏览器时,它会多次触发 SQLDependency 事件。

这是我的Repository.cs

  public class Repository
{
    private static string conString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString();
    public List<GetTakeInCount> UpdateTRTakeInData()
    {
        try
        {
            var lst = new List<GetTakeInCount>();
            using (SqlConnection con = new SqlConnection(conString))
            {

                using (var cmd = new SqlCommand(@"SELECT [Date],[TotalPlan],[TakeInQty],[OrderQty],[DelayedQty] FROM [dbo].[ProductTakeInData] Where [Production] = 'TR'", con))
                {
                    cmd.Notification = null;

                    if (con.State == ConnectionState.Closed)
                        con.Open();

                    SqlDependency dependency = new SqlDependency(cmd);
                    dependency.OnChange -= new OnChangeEventHandler(dependency_OnChange);
                    dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

                    var rdr = cmd.ExecuteReader();
                    while (rdr.Read())
                    {
                        GetTakeInCount rowData = new GetTakeInCount();
                        rowData.TakeInQuantity = Convert.ToDouble(rdr["TakeInQty"].ToString());
                        rowData.Date = rdr["Date"].ToString();
                        rowData.PlanQuantity = rdr["TotalPlan"].ToString();
                        rowData.AccPlanQty = Convert.ToDouble(rdr["TotalPlan"].ToString());
                        rowData.OrderQty = Convert.ToDouble(rdr["OrderQty"].ToString());
                        rowData.DelayedQty = Convert.ToDouble(rdr["DelayedQty"].ToString());
                        lst.Add(rowData);
                    }
                    rdr.Dispose();
                }
            }

            return lst;
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    private void dependency_OnChange(object sender, SqlNotificationEventArgs e) //this will be called when any changes occur in db table. 
    {
        if (e.Type == SqlNotificationType.Change)
            {
            //Call SignalR  
            MyHub mh = new MyHub();
            mh.UpdateChart();
        }
        SqlDependency dependency = sender as SqlDependency;
        if (dependency != null) dependency.OnChange -= new OnChangeEventHandler(dependency_OnChange);
    }

}

这是我的中心

[HubName("MyHub")]
    public class MyHub : Hub
    {

       public void UpdateChart()  
       {
            List<GetTakeInCount> data = new List<GetTakeInCount>();
            Repository rep = new Repository();
            data = rep.UpdateTRTakeInData();
            IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
            context.Clients.All.updateChartData(data);
        }  

    }

这是我的js素材:

 $(function () {
        // Declare a proxy to reference the hub.


        var chartConnection = $.connection.MyHub;
        $.connection.hub.logging = true;

        //debugger;
        // Create a function that the hub can call to broadcast messages.
        chartConnection.client.updateChartData = function () {
            updateChart();
            console.log('hub started')

        };
        // Start the connection.
        $.connection.hub.start();
        updateChart();

    });

        function updateChart()
        {                                         
    -- Update Chart Code ---
    }

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

Ryan,您可以重新查看事件注销和注册部分。

SqlDependency dependency = new SqlDependency(cmd); dependency.OnChange -= new OnChangeEventHandler(dependency_OnChange); dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

我认为最好具有SqlDependency的单例对象,然后注销该对象并进行注册。

为此,您可以创建一个单例类,该类将为您提供SqlDependency的实例,而无需执行“ new SqlDependency(cmd)”,您可以调用singletonclass的getInstance(cmd)方法并在其上注销并注册那个。