vb.net 中可能有多个 sqldependency 吗?

发布于 2024-12-29 18:56:31 字数 4625 浏览 1 评论 0原文

基本上我的代码是基于这里 http://www.dreamincode。 net/forums/topic/185244-using-sqldependency-to-monitor-sql-database-changes/

目前的情况是我有 2 个表希望监控所以我简单地用第一个 sqldependancy 复制另一个类似的代码,但它失败了,并且似乎最新的 sqldependancy 将取代以前的 sqldependancy 函数。

这是我的代码,

 Public Sub GetNames()
        If Not DoesUserHavePermission() Then
            Return
        End If


        lbQueue.Items.Clear()

        ' You must stop the dependency before starting a new one.
        ' You must start the dependency when creating a new one.
        Dim connectionString As String = GetConnectionString()
        SqlDependency.Stop(connectionString)
        SqlDependency.Start(connectionString)


        Using cn As SqlConnection = New SqlConnection(connectionString)

            Using cmd As SqlCommand = cn.CreateCommand()

                cmd.CommandType = CommandType.Text
                cmd.CommandText = "SELECT PatientID FROM dbo.[patient_queue]"

                cmd.Notification = Nothing

                ' creates a new dependency for the SqlCommand
                Dim dep As SqlDependency = New SqlDependency(cmd)
                ' creates an event handler for the notification of data changes in the database
                AddHandler dep.OnChange, AddressOf dep_onchange

                cn.Open()

                Using dr As SqlDataReader = cmd.ExecuteReader()

                    While dr.Read()

                        lbQueue.Items.Add(dr.GetInt32(0))
                        doctor.lbqueue.items.add(dr.GetInt32(0))

                    End While

                End Using

            End Using

        End Using
    End Sub

    Private Sub dep_onchange(ByVal sender As System.Object, ByVal e As System.Data.SqlClient.SqlNotificationEventArgs)

        ' this event is run asynchronously so you will need to invoke to run on the UI thread(if required)
        If Me.InvokeRequired Then

            lbQueue.BeginInvoke(New MethodInvoker(AddressOf GetNames))
            My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Asterisk)

        Else

            GetNames()

        End If

        ' this will remove the event handler since the dependency is only for a single notification
        Dim dep As SqlDependency = DirectCast(sender, SqlDependency)
        RemoveHandler dep.OnChange, AddressOf dep_onchange

    End Sub


    Public Sub GetMedID()
        If Not DoesUserHavePermission() Then
            Return
        End If


        lbMedQueue.Items.Clear()

        ' You must stop the dependency before starting a new one.
        ' You must start the dependency when creating a new one.
        Dim connectionString As String = GetConnectionString()
        SqlDependency.Stop(connectionString)
        SqlDependency.Start(connectionString)


        Using cn As SqlConnection = New SqlConnection(connectionString)

            Using cmd As SqlCommand = cn.CreateCommand()

                cmd.CommandType = CommandType.Text
                cmd.CommandText = "SELECT RecordID FROM dbo.[medicine_queue]"

                cmd.Notification = Nothing

                ' creates a new dependency for the SqlCommand
                Dim dep As SqlDependency = New SqlDependency(cmd)
                ' creates an event handler for the notification of data changes in the database
                AddHandler dep.OnChange, AddressOf dep_onchange2

                cn.Open()

                Using dr As SqlDataReader = cmd.ExecuteReader()

                    While dr.Read()

                        lbMedQueue.Items.Add(dr.GetInt32(0))


                    End While

                End Using

            End Using

        End Using
    End Sub


    Private Sub dep_onchange2(ByVal sender As System.Object, ByVal e As System.Data.SqlClient.SqlNotificationEventArgs)

        ' this event is run asynchronously so you will need to invoke to run on the UI thread(if required)
        If Me.InvokeRequired Then

            lbMedQueue.BeginInvoke(New MethodInvoker(AddressOf GetMedID))
            My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Asterisk)

        Else

            GetMedID()

        End If

        ' this will remove the event handler since the dependency is only for a single notification
        Dim dep As SqlDependency = DirectCast(sender, SqlDependency)
        RemoveHandler dep.OnChange, AddressOf dep_onchange2

    End Sub

最后我在加载表单上调用了 GetNames,GetMedID,它工作正常,只是 GetMedID 正在运行,并且 GetNames 在 onchanged 时不会触发事件。

Basically my code is based on here
http://www.dreamincode.net/forums/topic/185244-using-sqldependency-to-monitor-sql-database-changes/

Current situation is i'm having 2 table wish to monitor so i simple duplicate another similar code with first sqldependancy, but it's failed and seem like the latest sqldependancy will replace the previous sqldependancy function.

here is the code of mine

 Public Sub GetNames()
        If Not DoesUserHavePermission() Then
            Return
        End If


        lbQueue.Items.Clear()

        ' You must stop the dependency before starting a new one.
        ' You must start the dependency when creating a new one.
        Dim connectionString As String = GetConnectionString()
        SqlDependency.Stop(connectionString)
        SqlDependency.Start(connectionString)


        Using cn As SqlConnection = New SqlConnection(connectionString)

            Using cmd As SqlCommand = cn.CreateCommand()

                cmd.CommandType = CommandType.Text
                cmd.CommandText = "SELECT PatientID FROM dbo.[patient_queue]"

                cmd.Notification = Nothing

                ' creates a new dependency for the SqlCommand
                Dim dep As SqlDependency = New SqlDependency(cmd)
                ' creates an event handler for the notification of data changes in the database
                AddHandler dep.OnChange, AddressOf dep_onchange

                cn.Open()

                Using dr As SqlDataReader = cmd.ExecuteReader()

                    While dr.Read()

                        lbQueue.Items.Add(dr.GetInt32(0))
                        doctor.lbqueue.items.add(dr.GetInt32(0))

                    End While

                End Using

            End Using

        End Using
    End Sub

    Private Sub dep_onchange(ByVal sender As System.Object, ByVal e As System.Data.SqlClient.SqlNotificationEventArgs)

        ' this event is run asynchronously so you will need to invoke to run on the UI thread(if required)
        If Me.InvokeRequired Then

            lbQueue.BeginInvoke(New MethodInvoker(AddressOf GetNames))
            My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Asterisk)

        Else

            GetNames()

        End If

        ' this will remove the event handler since the dependency is only for a single notification
        Dim dep As SqlDependency = DirectCast(sender, SqlDependency)
        RemoveHandler dep.OnChange, AddressOf dep_onchange

    End Sub


    Public Sub GetMedID()
        If Not DoesUserHavePermission() Then
            Return
        End If


        lbMedQueue.Items.Clear()

        ' You must stop the dependency before starting a new one.
        ' You must start the dependency when creating a new one.
        Dim connectionString As String = GetConnectionString()
        SqlDependency.Stop(connectionString)
        SqlDependency.Start(connectionString)


        Using cn As SqlConnection = New SqlConnection(connectionString)

            Using cmd As SqlCommand = cn.CreateCommand()

                cmd.CommandType = CommandType.Text
                cmd.CommandText = "SELECT RecordID FROM dbo.[medicine_queue]"

                cmd.Notification = Nothing

                ' creates a new dependency for the SqlCommand
                Dim dep As SqlDependency = New SqlDependency(cmd)
                ' creates an event handler for the notification of data changes in the database
                AddHandler dep.OnChange, AddressOf dep_onchange2

                cn.Open()

                Using dr As SqlDataReader = cmd.ExecuteReader()

                    While dr.Read()

                        lbMedQueue.Items.Add(dr.GetInt32(0))


                    End While

                End Using

            End Using

        End Using
    End Sub


    Private Sub dep_onchange2(ByVal sender As System.Object, ByVal e As System.Data.SqlClient.SqlNotificationEventArgs)

        ' this event is run asynchronously so you will need to invoke to run on the UI thread(if required)
        If Me.InvokeRequired Then

            lbMedQueue.BeginInvoke(New MethodInvoker(AddressOf GetMedID))
            My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Asterisk)

        Else

            GetMedID()

        End If

        ' this will remove the event handler since the dependency is only for a single notification
        Dim dep As SqlDependency = DirectCast(sender, SqlDependency)
        RemoveHandler dep.OnChange, AddressOf dep_onchange2

    End Sub

finally i called GetNames,GetMedID on load form, it worked fine,just GetMedID is functioning and GetNames does not firing event when onchanged.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你不是我要的菜∠ 2025-01-05 18:56:31

我认为这里的主要问题是您在每个数据访问方法中调用 .Stop 然后调用 .Start ,从而在每次访问时取消并重新启动依赖项方法。

您只需在应用程序启动时调用 .Start 一次,并在应用程序结束时调用 .Stop 类似。

例如,在 Web 应用程序中,最好的位置是 Global.asax Application_StartApplication_End 事件。

I think the main problem here is that you are calling .Stop and then .Start within each of your data access methods, thus cancelling and restarting the dependency each time you access the methods.

You just need to call .Start once when your application starts, and similarly .Stop when it ends.

For example, in a web application the best place for this is the Global.asax Application_Start and Application_End events.

静水深流 2025-01-05 18:56:31

我认为你是对的,我遇到了同样的问题。即使在 New SqlDependency(cmd) 之后,对 SqlDependency.Start(connectionString) 的第二次调用也会替换现有的初始默认 Service Broker 服务和队列。

Service Broker 在每次启动时使用 GUID 作为服务和队列名称的一部分创建默认服务和队列:Service{GUID} 和 Queue{GUID} - 但似乎只有一个默认服务/队列对可用,

您可以验证这是通过在第一个 Start 之后和第二个 Start 之后立即放置一个断点来实现的。转到 SQL Server,转到您的 dBase 并查看
Service Broker/服务和 Service Broker/队列文件夹。您需要右键单击“服务”和“队列”文件夹,然后在第二个断点后选择“刷新”

I think you are right, I ran into the same issue. A second call to SqlDependency.Start(connectionString), even after a New SqlDependency(cmd), replaced the existing, initial default Service Broker service and queue.

Service Broker creates a default Service and Queue on each Start using the a GUID as part of the Service and Queue names: Service{GUID} and Queue{GUID} - but there seems to only be one defualt Service/Queue pair available

You can verify this by putting a break-point immediately after the first Start and immediately after the second Start. Go to SQL Server, go to your dBase and look at the
Service Broker/Services and Service Broker/Queues folders. You'll need to right-click on the Services and Queues folders and select refresh after the second break-point

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文