0

I have a VB.net program that has a splashscreen. While the main window is loading, I search the network with a multithreading solution I created. I.e. It calls two other classes that each send out a broadcast packet, parses it, and then sends it in a list back to the main window. Once that's done I make a datatable of it and send it to the datagridview on the GUI. I also adjust the datagridview's columns, and a few other visual things. This is all done in a function called updateTable()

Here's some code to give some perspective :

 Private Sub MainWindow_Load(sender As Object, e As EventArgs) Handles Me.Load

    'search network for data & update the datagridview's table
    updateTable()

    'fix label to show number of items found
    lblCamNumber.Text = Me.devicesDataGridView.RowCount.ToString & " of devices Found"
End Sub

This setup was working fine originally, but I only recently added multithreading into the updateTable() function. Because of it, once in a blue moon I will get a BeginInvoke error. Saying, " cannot be called on a control until the window handle has been created."

From what I've seen on here, this usually means that I am trying to activate or adjust a control that hasn't been created yet in my splashscreen (there's no SQL server involved at all). I'm pretty certain this has to do with the way windows is initializing the form (i.e. from here A random cross-thread operation exception for Winforms multithreaded UI operation)

But I'm not calling (at least not in my code, windows may be) beginInvoke ever or any other lines. What can I do to my main window to make sure that this is fixed? Would moving the label update to another function help?

It should also be noted that the splashscreen has no code inside of its load function.

Here's a little bit of Updatetable() also,for clarity:

   Private Function updateTable() As Boolean

    'clean table
    devicesDataGridView.DataSource = Nothing

    'search for devices
    Try
        listOfdevices = searchNetwork()' <- multithreading is in here
    Catch ex As Exception
        Return False
    End Try

    'new datatable
    Dim dt As DataTable = setupTable()

    'add to datagridview
    Dim i As Integer = 0

    'add nothing if it is empty
    If listOfdevices Is Nothing Then
        Return True
    End If

    For Each d As device In listOfdevoces

        'update table
        dt.Rows.Add(False, i, d.hostname, d.brand, d.mac, d.model, d.firmware, _
                    d.ipaddr, d.port, d.ipgate, d.chan, d.encoder, _
                    d.DHCPen, d.MDen, d.OSD, d.res, d.bitrate, d.fps, _
                    d.audio, d.camtime, _
                    d.camdate, d.Username, d.Password, d.ResolutionsArray)
        i = i + 1
    Next

    '################
    '# Table Visuals
    '################

    'Column edit
    With devicesDataGridView
        Try
            'assign data
            devicesDataGridView.DataSource = dt

            cleanupTable()  'clean up formatting, text color, etc
        Catch ex As Exception

        End Try


    End With

    Return True

End Function

EDIT:

Someone requested the full error:

   System.InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
      at System.Windows.Forms.Control.WaitForWaitHandle(WaitHandle waitHandle)
      at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
      at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
      at System.Windows.Forms.Control.Invoke(Delegate method)
      at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HideSplashScreen()
      at               Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MainFormLoadingDone(Object sender, EventArgs e)
      at System.EventHandler.Invoke(Object sender, EventArgs e)
      at System.Windows.Forms.Form.OnLoad(EventArgs e)
      at System.Windows.Forms.Form.OnCreateControl()
      at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
      at System.Windows.Forms.Control.CreateControl()
      at System.Windows.Forms.Control.WmShowWindow(Message& m)
      at System.Windows.Forms.Control.WndProc(Message& m)
      at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
      at System.Windows.Forms.Form.WmShowWindow(Message& m)
      at System.Windows.Forms.Form.WndProc(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
      at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr        lparam)
Community
  • 1
  • 1
Kat
  • 2,460
  • 2
  • 36
  • 70
  • Can you post full exception info please? Stack trace and all – Sam Makin Aug 28 '14 at 14:20
  • It should be noted, this happened only in the .exe's splashscreen, not the debug. So I only got this in the JIT. – Kat Aug 28 '14 at 14:36
  • http://stackoverflow.com/questions/17603339/invoke-or-begininvoke-cannot-be-called-on-a-control-until-the-window-handle-has – Sam Makin Aug 28 '14 at 14:45
  • 1
    Also try changing the call from the load event to form.shown event to ensure that the control has been created first – Sam Makin Aug 28 '14 at 14:47
  • Very similar http://www.codeproject.com/Questions/549373/InvokeplusorplusBeginInvokepluscannotplusbepluscal – Sam Makin Aug 28 '14 at 14:52
  • @SamMakin I did move it to Forms.Shown, and still had the issue as suggested – Kat Aug 28 '14 at 14:54
  • Okay, I tried this method. Worked 4 times in a row. I think this was the solution:http://pjgcreations.blogspot.com/2012/10/windows-forms-app-with-splash-screen.html – Kat Aug 28 '14 at 14:56
  • WELP, it came up again. I'll follow the other comments and see what they have to offer. – Kat Aug 28 '14 at 16:20

0 Answers0