Multithreaded dynamic form generation/handling

NssB

Member
Joined
May 11, 2007
Messages
13
Programming Experience
Beginner
Hi all,

I appreciate this is somewhat of a complicated idea to grasp, however I'm sure there is someone out there capable of figuring this out :)

Background:
I have 3 forms: Update form, Reader Form and Popup Notification form. I add data to the DB from the "Update Form" and the "Reader Form" has a DataGridView which is refreshed constantly using a BackgroundWorker thread until the Form is closed (Manually). Depending on the type of data entered to DB and subsequently "read"........the Reader Form will instantiate a Popup Notification (popup form). On the popup form is a few labels and a Button. The button simply updates a field in the DB to acknowledge that the user has seen the popup.(ack_time).


Background DoWork routine (Reader form):
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim intX = 2
        Do While intX <> 1
            Dim da2 As DataTable = updateHighTable()
            Dim da As DataTable = updateLowMedTable()
            Dim arrPopups As New List(Of String)
            For Each strRow As DataRow In da2.Rows
                Dim popExists As Boolean = True
                ' If HIGH assignment is not acknowledged, loop through all open forms
                If strRow.IsNull(3) 
                    For ix As Integer = Application.OpenForms.Count - 1 To 0 Step -1
                        Dim frm = Application.OpenForms(ix) 'Get a handle on the current form being iterated over
                        'Check form name lookup for popups
                        If frm.Name = "assPopup" Then ' If the form name is assPopup, continue
                            'Cast the current form and add the (incident number) to list of Strings
                            If frm.IsHandleCreated Then
                                Dim currForm As assPopup = DirectCast(frm, assPopup)
                                Dim strString As String = CStr(currForm.GetPopupTag)
                                arrPopups.Add(strString)
                            End If
                        End If
                    Next
                    'Check if list of strings contains the current incident number
                    If arrPopups.Contains(strRow(0).ToString) Then
                        popExists = True
                    Else
                        popExists = False
                    End If
                End If
                ' If the current incident is not matched in the popup list, start new popup
                If popExists = False Then
                    BackgroundWorker1.ReportProgress(3, New controlNewAss(strRow))
                    'Threading.Thread.Sleep(1000)
                End If
            Next

            BackgroundWorker1.ReportProgress(1, New controlDGV(DataGridView1, da))
            BackgroundWorker1.ReportProgress(2, New controlDGV(DataGridView2, da2))

            Threading.Thread.Sleep(500)

            If BackgroundWorker1.CancellationPending Then
                MsgBox("AutoRefresh is stopped")
                Exit Do
            End If
        Loop
        If BackgroundWorker1.CancellationPending Then
            e.Cancel = True
            BackgroundWorker1.ReportProgress(100, "Cancelled.")
        End If
    End Sub


Popup Form Class:
Imports System.Data.OleDb

Public Class assPopup

    Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    End Sub

    Private Delegate Function getPopupTagInvoker() As String

    Public Function GetPopupTag() As String
        Dim text As String = ""
        If Me.Label3.InvokeRequired And Not Me.IsDisposed Then
            Try
                text = CStr(Me.Label3.Invoke(New getPopupTagInvoker(AddressOf GetPopupTag)))
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        Else
            text = Me.Label3.Text
        End If
        Return text
    End Function

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim lbl3 As String = Me.Label3.Text
        Dim strSql = "UPDATE assignments SET ack_time=GETUTCDATE() WHERE Ticket = '" & lbl3 & "'"
        Dim con As OleDbConnection = dbConnect()
        Dim cmd = New OleDbCommand(strSql, con)
        con.Open()
        Try
            cmd.ExecuteNonQuery()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
        con.Close()
        Me.Close()
    End Sub
End Class



The user upon submission of the correct type of data will receive a popup.....and can continue to receive popups for as many rows of this data type have not been acknowledged.
The user can acknowledge the popups in any order at any time.


The problem:
---------------

I get a seemingly random error which informs me that I cannot access a disposed object 'label'. This would appear to be the label I'm accessing on the Popup form. This is generated when I click on the Acknowledge button on the Popup.

My guess is, that the inner "For Loop" is trying to act on a disposed Popup Form.........but I cannot for the life of me understand why. I think the app is threadsafe at this point, but I'd like someone to correct me otherwise (limited Multi-threading experience)



Any help here would be very much appreciated!
 
Last edited by a moderator:
Top Bottom