I am using the SQLDependency class to listen for SQL notifications and the SQLDependency.OnChange event is executed on a different thread from the UI thread. My intention is to update the data in a grid view when this event is fired so SQL server database changes can instantly be reflected in the grid.
If I run my LoadData
method to reload the data into the grid I get a cross-threading error:
I have created a custom class to hold all the SQLDependency related code, and there is a single instance of this class declared globally across my application. I have an event on the class that is raised inside the SQLDependency.OnChanged event. This event is then handled on various different forms so their data can be reloaded. However, because the OnChange event is raised on a different thread, I need to add logic to run first:
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
I would prefer to avoid having to duplicate this code and copy it to each for where my custom event is handled. This answer is pretty much exactly what I am looking for but I can't figure out how to implement the code provided.
Logic down the lines of, get the invocation list of the event and get the thread of one of the handlers, then raise the event on that thread. With my limited experience I am unable to write code to do this on my own. Any assistance would be appreciated.
Objective: Raise an event on the UI thread with no extra code repeated in the event handlers.
Solution: Run this code on the target thread ahead of time (e.g. class constructor).
objSyncContext = SynchronizationContext.Current
Call this method RunOnUIThread(AddressOf RefreshData)
from another thread to run the referenced method on the target thread.
Delegate Sub CallDelegate()
Private Sub RunOnUIThread(objEvent As CallDelegate)
If objSyncContext Is Nothing Then
objEvent()
Else
objSyncContext.Post(Sub() objEvent(), Nothing)
End If
End Sub