首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SqlDependency与signalR没有一致地触发dependency_OnChange

SqlDependency与signalR没有一致地触发dependency_OnChange
EN

Stack Overflow用户
提问于 2016-09-21 20:26:56
回答 1查看 3K关注 0票数 2

设置

·2010

·IIS 8.5

·.NET框架4.6

·Microsoft SQL Server 2014

·IIS上的AppPool帐户是域\web

我有一个网页,可以监视数据库表中的更改。我使用dependency_OnChange来监视数据库,并通过signalR将数据传递给用户。我在dependency_OnChange方法中设置了一个断点,在数千次数据库更新中,它只被击中了几次。

在web.config..。我正在使用集成Security=True。

我的用户是sql框上的系统管理员。(这只是为了证明概念)

在Global.asax..。指定队列名、停止和启动and依赖项

代码语言:javascript
复制
void Application_Start(object sender, EventArgs e)
{
    var queuename = "Q_Name";
    var sConn = ConfigurationManager.ConnectionStrings["singalR_ConnString"].ConnectionString;
    SqlDependency.Stop(sConn, queuename);
    SqlDependency.Start(sConn, queuename);
}

void Application_End(object sender, EventArgs e)
{  
    var queuename = "Q_Name";
    var sConn = ConfigurationManager.ConnectionStrings["singalR_ConnString"].ConnectionString;
    SqlDependency.Stop(sConn, queuename);
}

在密码背后..。

代码语言:javascript
复制
public void SendNotifications()
{
    //Identify Current User and Row No
    string CurrentUser = GetNTName();


    string message = string.Empty;
    string conStr = ConfigurationManager.ConnectionStrings["singalR_ConnString"].ConnectionString;

    using (SqlConnection connection = new SqlConnection(conStr))
    {
        string query = "SELECT [RowNo] FROM [dbo].[Test] WHERE [User] =  @User";
        string SERVICE_NAME = "Serv_Name";

        using (SqlCommand command = new SqlCommand(query, connection))
        {
            // Add parameters and set values.
            command.Parameters.Add("@User", SqlDbType.VarChar).Value = CurrentUser;
            //Need to clear notification object
            command.Notification = null;
            //Create new instance of sql dependency eventlistener (re-register for change events)
            SqlDependency dependency = new SqlDependency(command, "Service=" + SERVICE_NAME + ";", 0);
            //SqlDependency dependency = new SqlDependency(command);
            //Attach the change event handler which is responsible for calling the same SendNotifications() method once a change occurs.
            dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
            connection.Open();
            SqlDataReader reader = command.ExecuteReader();

            if (reader.HasRows)
            {
                reader.Read();
                message = reader[0].ToString();
            }
        }
    }
    //If query returns rows, read the first result and pass that to hub method - NotifyAllClients.
    NotificationsHub nHub = new NotificationsHub();
    nHub.NotifyAllClients(message);
}


private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{            
    //Check type to make sure a data change is occurring
    if (e.Type == SqlNotificationType.Change)
    {
        // Re-register for query notification SqlDependency Change events.
        SendNotifications();
    }
}

NotificationsHub.cs页面..。

代码语言:javascript
复制
    //Create the Hub
    //To create a Hub, create a class that derives from Microsoft.Aspnet.Signalr.Hub. 

//Alias that can call class from javascript. - i.e.  var hub = con.createHubProxy('DisplayMessage');
[HubName("DisplayMessage")]
public class NotificationsHub : Hub //Adding [:Hub] let c# know that this is a Hub 
{
    //In this example, a connected client can call the NotifyAllClients method, and when it does, the data received is broadcasted to all connected clients.

    //Create NotifyAllClients Method
    //public means accessible to other classes
    //void means its not returning any data
    public void NotifyAllClients(string msg)
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>();
        //When this method gets called, every single client has a function displayNotification() that is going to be executed
        //msg is the data that is going to be displayed to all clients.
        context.Clients.All.displayNotification(msg);                                                       
    }

}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-22 18:22:43

这里我要做的第一件事是将Sql依赖项设置重构到一个独立的方法中,并从发送通知中调用它。(SoC和DRY)因为如果您要在其他地方创建其他SqlDependencies,它们就会相互绊倒。其次,您正在创建一个新的NotificationsHub,您应该得到当前活动的集线器。

代码语言:javascript
复制
DefaultHubManager hubManager = new DefaultHubManager();
hub = hubManager.ResolveHub("NotificationsHub");
hub.NotifyAllClients(message);

还有一种比较老的方法来获得枢纽,但我不确定它是否还能工作。

代码语言:javascript
复制
GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>()

我在这个答案中也有一个简单版本的例子。Polling for database changes: SqlDependency, SignalR is Good

如果你有任何问题,请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39625995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档