Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem: Forms processing in order opened?

Status
Not open for further replies.

Sorwen

Technical User
Nov 30, 2002
1,641
0
0
US
I have a multi-form program each window should be running independent of the other. The problem is that for some reason the second window will not process until the first is finished. I just ran it again and now they are working in reverse order.

A little background so you will understand some things in the code. StatusList is a control that takes a collection of StatusListItems. This is placed on CheckList_frm that just keeps track of progress and other information of the individual forms. query_frm just handles data collection that each main_frm will then process. query_frm_DataReady is an event raised on the query_frm once complete, but handled on the CheckList_frm.

Here is the code that creates the form.
Code:
    Private Sub query_frm_DataReady(ByVal Table As DataTable)
        If Me.InvokeRequired Then
            Me.Invoke(New delStartSessions(AddressOf StartSessions), Table)
        Else
            StartSessions(Table)
        End If
    End Sub

    Public Delegate Sub delStartSessions(ByVal Table As DataTable)
    Public Sub StartSessions(ByVal Table As DataTable)
        If qfrm IsNot Nothing Then
            If qfrm.Visible = True Then qfrm.Close()
            qfrm = Nothing
            GC.Collect()
        End If

        If Table IsNot Nothing Then
            If Table.Rows.Count > 0 Then
                Dim WindowNumber As Integer = CInt(nud_tss.value + 0.5)
                Dim WindowCount As Integer = 0
                Dim SplitTable As Integer = Table.Rows.Count / Me.nud_tss.value
                Dim MaxCount As Integer = SplitTable
                Dim LastCount As Integer = 0

                Me.run_tssb.Enabled = False

                For count As Integer = 1 To nud_tss.value
                    Dim newMainFrm As main_frm
                    Dim formDataRow(MaxCount - 1) As DataRow
                    Dim rowCount As Integer

                    newMainFrm = New main_frm
                    newMainFrm.Name = "main_frm_" & count
                    newMainFrm.Text = newMainFrm.Name
                    newMainFrm.ShowInTaskbar = False
                    
                    For rowCount = 1 To MaxCount
                        formDataRow(rowCount - 1) = Table.Rows((LastCount + rowCount) - 1)
                    Next

                    If count <> nud_tss.value Then
                        LastCount += rowCount - 1
                        MaxCount = ((Table.Rows.Count - LastCount) / (nud_tss.value - count))
                    End If

                    Dim cWBdata As New StatusListItem
                    cWBdata.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
                    cWBdata.AutoSize = True
                    cWBdata.Text = "main_frm_" & count
                    cWBdata.EmailStatus = StatusListItem.StatusType.NoEmail

                    cWBdata.SetStatusChange = StatusListItem.CheckMarkStatus.NotChecked
                    cWBdata.AutoSize = True
                    cWBdata.HideStatus = True
                    cWBdata.ProgressVisible = True
                    cWBdata.Minimum = 0
                    cWBdata.Maximum = formDataRow.Length
                    cWBdata.Value = 0
                    cWBdata.ListItemProgressBar.TextStyle = clCustomControls.CustomProgressBar.BarTextStyle.ValueOfMax
                    AddHandler cWBdata.Click, AddressOf ListItem_Click
                    AddHandler cWBdata.DoublClick, AddressOf ListItemDoubleClick
                    AddHandler cWBdata.ListItemContextMenuItemClick, AddressOf ListItemContextMenuClick
                    StatusList.Add(cWBdata)

                    cWBdata = Nothing

                    If My.Settings.AutoDock = True Then
                        Dim AvailableArea As System.Drawing.Rectangle

                        If My.Settings.SpreadWindows = False Then
                            AvailableArea = New System.Drawing.Rectangle(Me.Location.X + Me.Width, Me.Location.Y, CurrentScreen.WorkingArea.Width - Me.Width, Me.Height)
                        Else
                            Dim DualScreen As New clDualScreen.DualScreen
                            AvailableArea = DualScreen.TotalScreenArea(Me)
                        End If

                        If nud_tss.value > 1 Then
                            Dim x, y, w, h As Integer

                            If AvailableArea.Width >= AvailableArea.Height Then
                                If (count Mod 2) = 0 Then
                                    w = AvailableArea.Width / 2
                                    h = AvailableArea.Height / (WindowNumber / 2)
                                    x = Me.Width + w
                                    y = AvailableArea.Y + ((h * (count / 2)) - h)
                                Else
                                    Dim t As Integer = (count Mod 1)
                                    w = AvailableArea.Width / 2
                                    h = AvailableArea.Height / (WindowNumber / 2)
                                    x = Me.Width
                                    y = AvailableArea.Y + ((h * ((count + 1) / 2)) - h)
                                End If
                            End If

                            newMainFrm.Bounds = New System.Drawing.Rectangle(x, y, w, h)
                        Else
                            newMainFrm.Bounds = My.Settings.IcomsScreenDefaultSize
                        End If
                    End If

                    
                    newMainFrm.ProcessDataRows = formDataRow
                    newMainFrm.Show()
                Next

                sMessage("Total Records: " & Table.Rows.Count)
                Me.Focus()
            End If
        End If
    End Sub

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
What does this program do exactly? It might help if you give a non-technical description.
 
It has 3 main portions. The first controls and reports back to the user the status of the others. Another connects to a remote system to run various queries and retrieve data. The data (600 records to 6000) is then split and then individual windows process corrections to another remote system. In the past it has only been one processes window and it works fine. We have about 50 programs that handle difference processes. This new one that runs multiple windows at the same time is having problems.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
So then, each window gets a fraction of the 600 to 6000 records? Does the main form fire off multiple threads and use the new windows to simply report the progress, or does each new window fire off it's own background thread?
 
Correct. The each new window creates one thread for it's own processing.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
I just remembered that in 2008 you can see the threads used. Actually I've had it wrong this whole time. The thread has only actually been used for part of the process and then it transfers back to the main thread for that form. That does explain why periodically the UI appeared "locked up". Fixing that is going to have to be a later project. I admit I've only ever half understood threading.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
I guess I still can't tell by the code you've posted and not knowing what the variables are. Here's how I think I would approach it

1. Main form fills DataTable
2. Main form processes data table to break them out into smaller tables (This could be in a background thread).
3. Next main thread creates one new form per new table (happening on the UI thread).
4. Main thread sets each form's DataTable property.
5. Main thread loops through forms collection, calling a routine in each which fires off the background worker in each.

I'm not sure if that helps much, but like I said, I still don't think I completely understand it. [thumbsup2]
 
I'll try that last part.

1) I do this of course. In this instance it might be a little misleading as these all have carry over names from pervious programs. The "main form" for the program is CheckList_frm.
2) and this (Checklist_frm)
3) The code shown is on the main thread for CheckList_frm and creates a main_frm for each set of rows.
4) I do this, but currently it is an array of DataRows.
5) The main processing has to work a lot with the UI and I though a background worker was not good for that sort of situation? Though I don't claim that from direct experience as I've never used one. I've always used standard threads or delegates and never used background worker threads. Still I'll give it a shot though and see what happens.

Thanks for the help.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Ah, one other thing the thread on main_frm is kicked off from the form load event. In case that makes some type of difference.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Some may already know this, but I didn't so I thought I would mention it. Here is what seem to have been happening. If a thread calls an event, delegate, etc that runs an Application.DoEvents that forces some part of that code to take precedents over everything else no matter how many different threads you have running. I didn't test it all the way to see if it was the full code for that or just anything after the Application.DoEvents or if it was due to multiple Application.DoEvents.

The annoying thing was there was nothing pointing to that bit of code causing the problem because the Application.DoEvents did part of what it should and made sure everything seemed to be running correctly.

It makes sense since it is running on the whole application, but then you would think there would be a way to do it on the form level. Maybe there is and I do not know how. Or maybe the only option is to thread around it all. Which is what I had to do and hopefully made my threading more efficient in the process. More than likely I just added another problem that I'll not notice for 3 years. Still just an fyi if anyone finds this thread while trying to figure something similar out.

-I hate Microsoft!
-Forever and always forward.
-My kingdom for a edit button!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top