SqlDependency subscription not dropped from dm_qn_subscriptions on shutdown

前端 未结 2 1030
别那么骄傲
别那么骄傲 2021-02-10 14:47

My SqlDependency works fine, and the Broker Queue and Service get dropped properly when the application exits (I do execute SqlDependency.Stop(...) as recommen

2条回答
  •  刺人心
    刺人心 (楼主)
    2021-02-10 15:24

    If you don't mind being a little cheezy, I've found a way to clean these up on exit...

    First, set a flag that the onDependencyChange can observe to let it know to not re-subscribe to the query.

    Second, set the flag and execute a do-nothing update that you know will trigger the dependency subscription.

     update foo_master set foo_bar = foo_bar where foo_id = @id;
    

    My dependency monitoring is done on individual rows, so I only have to tickle one row to get it to fire. It might not be something you'd want to do on a large result set.

    On my FormClosing event, I fire each of the dependencies before disconnecting.

    Partial code:

    Private _dependency As SqlDependency = Nothing
    Private _beingKilled = False
    
    ' dependency is set up in loadRecord(ByVal idRow as Integer)
    
    Private Sub onDependencyChange(ByVal sender As Object, ByVal e As SqlNotificationEventArgs)
        ' This event may occur on a thread pool thread; It is illegal to update the UI from a worker thread.
        ' The following code checks to see if it is safe update the UI.
        Dim iSync As ISynchronizeInvoke = CType(_connection.masterForm, ISynchronizeInvoke)
    
        ' If InvokeRequired returns True, the code is executing on a worker thread.
        If iSync.InvokeRequired Then
            Dim tempDelegate As New OnChangeEventHandler(AddressOf onDependencyChange) ' Create a delegate to perform the thread switch
            Dim args() As Object = {sender, e}
            iSync.BeginInvoke(tempDelegate, args) ' Marshal the data from the worker thread to the UI thread.
        Else
            RemoveHandler _dependency.OnChange, AddressOf onDependencyChange
            If Not _beingKilled Then loadRecord(_id)
        End If
    End Sub
    

    Then simply set _beingKilled to True and execute the do-nothing update.

提交回复
热议问题