[英].NET raise event on UI thread
我正在使用SQLDependency类来侦听 SQL 通知,并且SQLDependency.OnChange事件在与 UI 线程不同的线程上执行。 我的目的是在触发此事件时更新网格视图中的数据,以便 SQL 服务器数据库更改可以立即反映在网格中。
如果我运行LoadData
方法将数据重新加载到网格中,则会出现跨线程错误:
我创建了一个自定义类来保存所有与 SQLDependency 相关的代码,并且在我的应用程序中全局声明了这个类的一个实例。 我在SQLDependency.OnChanged事件中引发的类上有一个事件。 然后在各种不同的表单上处理此事件,以便可以重新加载它们的数据。 但是,因为OnChange事件是在不同的线程上引发的,所以我需要添加逻辑来首先运行:
Delegate Sub ReloadCallback()
Private Sub LoadOnUI()
If Me.InvokeRequired Then
Dim d As ReloadCallback = New ReloadCallback(AddressOf LoadOnUI)
Me.Invoke(d)
Else
Invoke(New MethodInvoker(Sub() RefreshData()))
End If
End Sub
我宁愿避免复制此代码并将其复制到每个处理我的自定义事件的地方。 这个答案几乎正是我正在寻找的,但我无法弄清楚如何实现所提供的代码。
逻辑向下,获取事件的调用列表并获取其中一个处理程序的线程,然后在该线程上引发事件。 由于我的经验有限,我无法自己编写代码来执行此操作。 任何援助将不胜感激。
目标:在 UI 线程上引发事件,在事件处理程序中没有重复的额外代码。
这是一个使用SynchronizationContext的快速示例。
请注意,它假定您是从主 UI 线程创建类,并从构造函数存储当前上下文:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim d As New Duck("Bob")
AddHandler d.Quack, AddressOf duck_Quack
Label1.Text = "Waiting for Quack..."
d.RaiseThreadedQuack(3)
End Sub
Private Sub duck_Quack(source As Duck)
Label1.Text = "Quack received from: " & source.Name
End Sub
End Class
Public Class Duck
Public ReadOnly Property Name() As String
Private sc As WindowsFormsSynchronizationContext
Public Sub New(ByVal name As String)
Me.Name = name
sc = WindowsFormsSynchronizationContext.Current
End Sub
Public Event Quack(ByVal source As Duck)
Public Sub RaiseThreadedQuack(ByVal delayInSeconds As Integer)
Dim T As New Threading.Thread(AddressOf ThreadedQuack)
T.Start(delayInSeconds)
End Sub
Private Sub ThreadedQuack(ByVal O As Object)
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(O).TotalMilliseconds)
sc.Post(AddressOf RaiseUIQuack, Me)
End Sub
Private Sub RaiseUIQuack(ByVal O As Object)
RaiseEvent Quack(O)
End Sub
End Class
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.