vb.net 中可能有多个 sqldependency 吗?
基本上我的代码是基于这里 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这里的主要问题是您在每个数据访问方法中调用
.Stop
然后调用.Start
,从而在每次访问时取消并重新启动依赖项方法。您只需在应用程序启动时调用
.Start
一次,并在应用程序结束时调用.Stop
类似。例如,在 Web 应用程序中,最好的位置是 Global.asax
Application_Start
和Application_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
andApplication_End
events.我认为你是对的,我遇到了同样的问题。即使在 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